blun-king-cli 9.1.586 → 9.1.588
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/CHANGELOG.md +11 -178
- package/LIESMICH.txt +51 -13
- package/README.md +44 -47
- package/agent-spine-plugin/.codex-plugin/plugin.json +16 -4
- package/agent-spine-plugin/CHANGELOG.md +37 -5
- package/agent-spine-plugin/README.md +3 -3
- package/agent-spine-plugin/blun.plugin.json +45 -10
- package/agent-spine-plugin/docs/artifact-evaluation.md +93 -0
- package/agent-spine-plugin/docs/host-integration.md +42 -27
- package/agent-spine-plugin/docs/preflight-recall.md +4 -2
- package/agent-spine-plugin/docs/session-timeline.md +97 -236
- package/agent-spine-plugin/docs/world-model.md +25 -0
- package/agent-spine-plugin/hooks/codex.json +1 -1
- package/agent-spine-plugin/hooks/hooks.json +1 -1
- package/agent-spine-plugin/package.json +1 -3
- package/agent-spine-plugin/scripts/check-hosts.js +3 -3
- package/agent-spine-plugin/scripts/release-check.js +10 -5
- package/agent-spine-plugin/scripts/run-checks.js +4 -1
- package/agent-spine-plugin/scripts/run-tests-hermetic.js +32 -6
- package/agent-spine-plugin/src/cli-learning.js +15 -0
- package/agent-spine-plugin/src/cli.js +2 -0
- package/agent-spine-plugin/src/hook.js +32 -32
- package/agent-spine-plugin/src/lib/action-lesson-recall.js +73 -8
- package/agent-spine-plugin/src/lib/briefing.js +146 -36
- package/agent-spine-plugin/src/lib/channel-continuity.js +19 -0
- package/agent-spine-plugin/src/lib/delivery-agent-usage.js +14 -7
- package/agent-spine-plugin/src/lib/gateway-group-response.js +128 -0
- package/agent-spine-plugin/src/lib/gateway-runs.js +24 -15
- package/agent-spine-plugin/src/lib/hook-briefing-use.js +13 -3
- package/agent-spine-plugin/src/lib/hook-context.js +16 -3
- package/agent-spine-plugin/src/lib/hook-output.js +129 -5
- package/agent-spine-plugin/src/lib/hook-timeline.js +5 -3
- package/agent-spine-plugin/src/lib/indexed-memory.js +2 -2
- package/agent-spine-plugin/src/lib/learning-artifact-evaluator.js +114 -0
- package/agent-spine-plugin/src/lib/learning-context.js +11 -4
- package/agent-spine-plugin/src/lib/learning-measurements.js +2 -2
- package/agent-spine-plugin/src/lib/mcp-runtime.js +89 -3
- package/agent-spine-plugin/src/lib/mcp-source-context.js +12 -2
- package/agent-spine-plugin/src/lib/mcp-timeline-tools.js +91 -8
- package/agent-spine-plugin/src/lib/mcp-world-tools.js +2 -2
- package/agent-spine-plugin/src/lib/owned-file-lock.js +20 -1
- package/agent-spine-plugin/src/lib/persona-runtime.js +2 -2
- package/agent-spine-plugin/src/lib/preflight-delivery-id.js +27 -0
- package/agent-spine-plugin/src/lib/preflight.js +4 -4
- package/agent-spine-plugin/src/lib/session-timeline-codex.js +15 -0
- package/agent-spine-plugin/src/lib/session-timeline-contract.js +12 -4
- package/agent-spine-plugin/src/lib/session-timeline-event-extract.js +36 -7
- package/agent-spine-plugin/src/lib/session-timeline-host-origin.js +13 -10
- package/agent-spine-plugin/src/lib/session-timeline-invocation.js +1 -1
- package/agent-spine-plugin/src/lib/session-timeline-king.js +14 -0
- package/agent-spine-plugin/src/lib/session-timeline-prior.js +18 -12
- package/agent-spine-plugin/src/lib/session-timeline-provider.js +5 -0
- package/agent-spine-plugin/src/lib/session-timeline-query.js +2 -0
- package/agent-spine-plugin/src/lib/session-timeline-results.js +35 -10
- package/agent-spine-plugin/src/lib/session-timeline-source-open.js +30 -0
- package/agent-spine-plugin/src/lib/session-timeline.js +122 -75
- package/agent-spine-plugin/src/lib/source-roots.js +3 -2
- package/agent-spine-plugin/src/lib/task-knowledge-context.js +22 -1
- package/agent-spine-plugin/src/lib/timeline-continuation-update.js +100 -0
- package/agent-spine-plugin/src/lib/timeline-tool-guard.js +30 -7
- package/agent-spine-plugin/src/lib/timeline-user-feedback.js +217 -0
- package/agent-spine-plugin/src/lib/timeline-world-capture.js +233 -0
- package/agent-spine-plugin/src/lib/world-knowledge.js +59 -2
- package/agent-spine-plugin/src/lib/world-model.js +64 -9
- package/agent-spine-plugin/src/worker.js +13 -1
- package/bin/blun.js +43 -28
- package/bin/core-bootstrap.js +5 -4
- package/bin/king.js +43 -28
- package/bin/launcher-mode.js +1 -10
- package/bin/launcher-runtime.js +128 -295
- package/bin/managed-node.js +0 -0
- package/bin/managed-plugin-selection.cjs +0 -1
- package/bin/native-module-repair.js +0 -0
- package/bin/node-runtime.js +0 -0
- package/bin/node-version.js +0 -0
- package/bin/plugin-bootstrap.js +56 -120
- package/bin/private-paths.js +11 -34
- package/bin/standard-tools-bootstrap.js +34 -114
- package/bin/turn-thinking-policy.cjs +3 -11
- package/bin/update-copy.js +200 -0
- package/bin/update-lease.js +0 -0
- package/bin/update-notice.js +136 -289
- package/bin/verify-agent-behavior.cjs +122 -0
- package/bin/verify-agent-components.cjs +104 -0
- package/bin/verify-bundled-agent-sources.cjs +57 -0
- package/blun.mjs +143078 -135241
- package/bundled-agent-sources.json +701 -0
- package/package.json +12 -15
- package/standard-skills/translate-native/README.md +1293 -0
- package/standard-skills/translate-native/SKILL.md +172 -22
- package/standard-skills/translate-native/VERSION +1 -1
- package/standard-skills/translate-native/agents/openai.yaml +18 -0
- package/standard-skills/translate-native/assets/icon.svg +8 -0
- package/standard-skills/translate-native/docs/BLUN_CODE_INTEGRATION.md +76 -0
- package/standard-skills/translate-native/docs/PREMORTEM.md +489 -0
- package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION.md +2035 -0
- package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION_API.md +1302 -0
- package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION_EVIDENCE_HTTP.md +136 -0
- package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION_HEALTH_HTTP.md +130 -0
- package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION_HTTP_PROVIDER.md +175 -0
- package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION_RECEIPT_VERIFIER_HTTP.md +86 -0
- package/standard-skills/translate-native/integrations/AGENT_RULES.md +32 -0
- package/standard-skills/translate-native/integrations/adapters/blun-code-language-guard.js +514 -0
- package/standard-skills/translate-native/integrations/adapters/node-language-guard.js +230 -0
- package/standard-skills/translate-native/integrations/audit_log.py +327 -0
- package/standard-skills/translate-native/integrations/claude_language_hook.js +1536 -0
- package/standard-skills/translate-native/integrations/commercial_localization_profile.py +42 -0
- package/standard-skills/translate-native/integrations/delivery-policy.example.json +28 -0
- package/standard-skills/translate-native/integrations/enforced_delivery.py +543 -0
- package/standard-skills/translate-native/integrations/guard_service.py +435 -0
- package/standard-skills/translate-native/integrations/language_gateway.py +67 -0
- package/standard-skills/translate-native/integrations/mcp_auth_headers.py +198 -0
- package/standard-skills/translate-native/integrations/mcp_http_gateway.py +429 -0
- package/standard-skills/translate-native/integrations/non_language_html_entities.js +1485 -0
- package/standard-skills/translate-native/integrations/pre_output_guard.py +65 -0
- package/standard-skills/translate-native/integrations/task_router.py +101 -0
- package/standard-skills/translate-native/integrations/website_localization.py +401 -0
- package/standard-skills/translate-native/integrations/website_localization_api.py +581 -0
- package/standard-skills/translate-native/integrations/website_localization_benchmark.py +1885 -0
- package/standard-skills/translate-native/integrations/website_localization_benchmark_campaign.py +1772 -0
- package/standard-skills/translate-native/integrations/website_localization_benchmark_candidate.py +506 -0
- package/standard-skills/translate-native/integrations/website_localization_benchmark_http.py +400 -0
- package/standard-skills/translate-native/integrations/website_localization_benchmark_review_store.py +781 -0
- package/standard-skills/translate-native/integrations/website_localization_benchmark_reviewer_http.py +500 -0
- package/standard-skills/translate-native/integrations/website_localization_benchmark_runtime.py +1107 -0
- package/standard-skills/translate-native/integrations/website_localization_benchmark_suite.py +463 -0
- package/standard-skills/translate-native/integrations/website_localization_cms.py +2835 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_client.py +875 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_dispatch.py +805 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_http.py +588 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_lifecycle_monitor.py +991 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_receiver.py +1441 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_receiver_runtime.py +414 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_receiver_store.py +1073 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_removal_dispatch.py +865 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_client.py +583 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery.py +964 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_runtime.py +665 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_http.py +1153 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_runtime.py +675 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_service.py +1125 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_terminal_notification.py +674 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_terminal_notification_http.py +444 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_terminal_notification_receiver.py +1469 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_terminal_notification_receiver_runtime.py +1142 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_terminal_processing_monitor.py +634 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_terminal_receiver_client.py +804 -0
- package/standard-skills/translate-native/integrations/website_localization_deepl_baseline.py +922 -0
- package/standard-skills/translate-native/integrations/website_localization_evidence_http.py +482 -0
- package/standard-skills/translate-native/integrations/website_localization_health.py +1541 -0
- package/standard-skills/translate-native/integrations/website_localization_health_http.py +372 -0
- package/standard-skills/translate-native/integrations/website_localization_http_provider.py +297 -0
- package/standard-skills/translate-native/integrations/website_localization_native_reference_http.py +479 -0
- package/standard-skills/translate-native/integrations/website_localization_native_reference_intake.py +363 -0
- package/standard-skills/translate-native/integrations/website_localization_native_reference_queue.py +1449 -0
- package/standard-skills/translate-native/integrations/website_localization_native_reference_store.py +420 -0
- package/standard-skills/translate-native/integrations/website_localization_quality_profiles.py +235 -0
- package/standard-skills/translate-native/integrations/website_localization_queue.py +671 -0
- package/standard-skills/translate-native/integrations/website_localization_receipt_verifier_http.py +516 -0
- package/standard-skills/translate-native/integrations/website_localization_release.py +928 -0
- package/standard-skills/translate-native/integrations/website_localization_release_coordinator.py +1008 -0
- package/standard-skills/translate-native/integrations/website_localization_runner.py +276 -0
- package/standard-skills/translate-native/integrations/website_localization_runtime.py +862 -0
- package/standard-skills/translate-native/integrations/website_localization_service.py +350 -0
- package/standard-skills/translate-native/integrations/website_localization_supervisor.py +511 -0
- package/standard-skills/translate-native/integrations/website_localization_worker.py +663 -0
- package/standard-skills/translate-native/provenance.json +3 -4
- package/standard-skills/translate-native/references/commercial-localization.md +177 -0
- package/standard-skills/translate-native/scripts/blun_language_guard.py +7 -1
- package/standard-skills/translate-native/scripts/check_commercial_review.py +80 -0
- package/standard-skills/translate-native/scripts/commercial_localization_profile.py +333 -0
- package/standard-tools/language-guard/LICENSE +21 -0
- package/standard-tools/language-guard/VERSION +1 -0
- package/standard-tools/language-guard/blun_language_guard.py +7 -1
- package/standard-tools/language-guard/check_commercial_review.py +80 -0
- package/standard-tools/language-guard/commercial_localization_profile.py +333 -0
- package/standard-tools/language-guard/language_gateway.py +62 -0
- package/standard-tools/language-guard/pre_output_guard.py +64 -0
- package/standard-tools/language-guard/provenance.json +4 -11
- package/standard-tools/manifest.json +34 -11
- package/telegram-plugin/commands/access.md +2 -10
- package/telegram-plugin/dist/bridge.mjs +64041 -687
- package/telegram-plugin/dist/mcp-server.mjs +72810 -9027
- package/telegram-plugin/dist/noise.mjs +28 -63511
- package/agent-spine-plugin/CONTRIBUTING.md +0 -52
- package/agent-spine-plugin/SECURITY.md +0 -47
- package/agent-spine-plugin/docs/assignment-continuation.md +0 -48
- package/agent-spine-plugin/docs/releasing.md +0 -85
- package/agent-spine-plugin/docs/structured-completion.md +0 -67
- package/bin/abort-listener-policy.cjs +0 -43
- package/bin/active-steer-priority-policy.cjs +0 -24
- package/bin/agent-api-http-adapter.mjs +0 -446
- package/bin/agent-api-private-http-server.mjs +0 -288
- package/bin/agent-api-runtime.mjs +0 -252
- package/bin/agent-api-service-environment.mjs +0 -236
- package/bin/agent-api-service-host.mjs +0 -209
- package/bin/agent-api-service-process.mjs +0 -171
- package/bin/agent-api-session-registry.mjs +0 -428
- package/bin/agent-api-tool-broker.cjs +0 -248
- package/bin/agent-api-turn-controller.mjs +0 -461
- package/bin/agent-api-usage-journal.cjs +0 -259
- package/bin/agent-resume-snapshot.cjs +0 -241
- package/bin/agentspine-king-goal-inbox.mjs +0 -111
- package/bin/agentspine-king-goal-intake.mjs +0 -106
- package/bin/approval-rejection-stop.cjs +0 -15
- package/bin/assistant-message-offload-policy.cjs +0 -284
- package/bin/baseline-skill-performance-policy.cjs +0 -39
- package/bin/bash-search-scope-policy.cjs +0 -49
- package/bin/codebase-search-runtime.cjs +0 -23
- package/bin/cognitive-action-checkpoint.cjs +0 -1104
- package/bin/cognitive-attention-delivery.cjs +0 -76
- package/bin/cognitive-attention-policy.cjs +0 -143
- package/bin/cognitive-attention-runtime.cjs +0 -91
- package/bin/cognitive-context-projection.cjs +0 -73
- package/bin/cognitive-cross-portal-acceptance.cjs +0 -443
- package/bin/cognitive-effective-view.cjs +0 -77
- package/bin/cognitive-focus-projection.cjs +0 -206
- package/bin/cognitive-focus-scope.cjs +0 -37
- package/bin/cognitive-goal-autostart-policy.cjs +0 -72
- package/bin/cognitive-goal-time-trigger-controller.cjs +0 -146
- package/bin/cognitive-memory-adapter.cjs +0 -282
- package/bin/cognitive-memory-command.cjs +0 -293
- package/bin/cognitive-memory-provider.cjs +0 -92
- package/bin/cognitive-salience-policy.cjs +0 -159
- package/bin/cognitive-state-store.cjs +0 -508
- package/bin/cognitive-turn-lifecycle.cjs +0 -624
- package/bin/cognitive-work-focus.cjs +0 -180
- package/bin/compaction-history-archive.cjs +0 -166
- package/bin/compaction-history-startup.cjs +0 -50
- package/bin/compaction-model-policy.cjs +0 -31
- package/bin/compaction-stage-policy.cjs +0 -21
- package/bin/compaction-transaction-policy.cjs +0 -122
- package/bin/config-write-dedup-policy.cjs +0 -27
- package/bin/context-budget-ledger.cjs +0 -31
- package/bin/context-doctor-policy.cjs +0 -70
- package/bin/context-insight-policy.cjs +0 -36
- package/bin/context-performance-policy.cjs +0 -15
- package/bin/context-pressure-policy.cjs +0 -20
- package/bin/cron-run-output.cjs +0 -45
- package/bin/cron-run-store.cjs +0 -145
- package/bin/curiosity-scout-policy.cjs +0 -49
- package/bin/default-model-output-budget-policy.cjs +0 -28
- package/bin/durable-task-resume-policy.cjs +0 -130
- package/bin/durable-task-resume-runtime.cjs +0 -117
- package/bin/durable-task-resume-store.cjs +0 -88
- package/bin/editable-tool-approval-policy.cjs +0 -540
- package/bin/editable-tool-approval-runtime.cjs +0 -99
- package/bin/effective-system-prompt-cache-policy.cjs +0 -33
- package/bin/error-memory-performance-policy.cjs +0 -113
- package/bin/file-observation-policy.cjs +0 -133
- package/bin/foreground-output-capture-policy.cjs +0 -41
- package/bin/generated-source-health.cjs +0 -142
- package/bin/glob-pattern-policy.cjs +0 -13
- package/bin/goal-completion-evidence-policy.cjs +0 -120
- package/bin/grep-output-limit-policy.cjs +0 -39
- package/bin/historical-media-projection-policy.cjs +0 -48
- package/bin/history-offload-pressure-policy.cjs +0 -33
- package/bin/html-to-research-markdown.cjs +0 -147
- package/bin/identity-context-policy.cjs +0 -764
- package/bin/identity-journal-policy.cjs +0 -107
- package/bin/input-draft-persistence.cjs +0 -77
- package/bin/king-tui-function-contract.json +0 -33
- package/bin/launcher-restart-policy.cjs +0 -150
- package/bin/live-response-repetition-guard.cjs +0 -196
- package/bin/llm-config-log-dedup-policy.cjs +0 -76
- package/bin/loop-event-record-policy.cjs +0 -174
- package/bin/managed-context-startup-policy.cjs +0 -27
- package/bin/media-activity-layout-policy.cjs +0 -34
- package/bin/media-auto-retrieval-policy.cjs +0 -90
- package/bin/media-result-policy.cjs +0 -59
- package/bin/micro-compaction-policy.cjs +0 -145
- package/bin/mistake-relevance-policy.cjs +0 -319
- package/bin/model-retry-progress-policy.cjs +0 -46
- package/bin/native-large-file-io.cjs +0 -42
- package/bin/native-runtime-cache.cjs +0 -76
- package/bin/natural-presence-policy.cjs +0 -28
- package/bin/noninteractive-shell-env-policy.cjs +0 -19
- package/bin/observer-hooks.cjs +0 -14
- package/bin/outbound-claim-provenance.cjs +0 -150
- package/bin/oversized-context-offload-policy.cjs +0 -86
- package/bin/pending-media-policy.cjs +0 -182
- package/bin/pending-token-estimate-policy.cjs +0 -41
- package/bin/personal-memory-consent-policy.cjs +0 -72
- package/bin/personal-memory-performance-policy.cjs +0 -12
- package/bin/personality-choice-policy.cjs +0 -101
- package/bin/personality-memory-adapter.cjs +0 -379
- package/bin/personality-mode.cjs +0 -46
- package/bin/personality-setup-policy.cjs +0 -197
- package/bin/proactive-compaction-policy.cjs +0 -25
- package/bin/profile-identity-resolution.cjs +0 -136
- package/bin/profile-runtime.cjs +0 -318
- package/bin/profile-tool-exclusion-policy.cjs +0 -37
- package/bin/programmatic-context-isolation.cjs +0 -25
- package/bin/programmatic-tool-runtime.mjs +0 -627
- package/bin/provider-idle-timeout-policy.cjs +0 -14
- package/bin/provider-model-refresh-deadline.cjs +0 -53
- package/bin/provider-model-refresh-policy.cjs +0 -107
- package/bin/rate-limit-recovery-policy.cjs +0 -47
- package/bin/read-batch-policy.cjs +0 -32
- package/bin/read-continuation-policy.cjs +0 -59
- package/bin/recurring-cron-history-policy.cjs +0 -124
- package/bin/relationship-continuity-policy.cjs +0 -143
- package/bin/relationship-curiosity-policy.cjs +0 -107
- package/bin/relationship-learning-policy.cjs +0 -168
- package/bin/release-artifact-freeze-policy.cjs +0 -30
- package/bin/reload-plugin-bootstrap.cjs +0 -18
- package/bin/reload-queue-policy.cjs +0 -38
- package/bin/repeated-assistant-response-policy.cjs +0 -232
- package/bin/repeated-injection-projection.cjs +0 -107
- package/bin/repeated-user-message-projection.cjs +0 -8
- package/bin/research-page-result.cjs +0 -74
- package/bin/retry-checkpoint-policy.cjs +0 -13
- package/bin/runtime-exit-ledger.cjs +0 -144
- package/bin/scoped-cron-run-policy.cjs +0 -358
- package/bin/session-checkpoint-policy.cjs +0 -25
- package/bin/session-compaction-policy.cjs +0 -84
- package/bin/session-replay-policy.cjs +0 -20
- package/bin/session-replay-window-policy.cjs +0 -40
- package/bin/session-resume-checkpoint.cjs +0 -254
- package/bin/session-scrollback-archive.cjs +0 -229
- package/bin/skill-activation-performance-policy.cjs +0 -69
- package/bin/skill-listing-performance-policy.cjs +0 -92
- package/bin/soul-organization-policy.cjs +0 -78
- package/bin/soul-preservation-policy.cjs +0 -20
- package/bin/startup-preferences.cjs +0 -131
- package/bin/streaming-flush-performance-policy.cjs +0 -28
- package/bin/structured-agent-swarm-output.cjs +0 -325
- package/bin/structured-subagent-output.cjs +0 -252
- package/bin/subagent-context-fork-policy.cjs +0 -155
- package/bin/subagent-max-tokens-handoff-policy.cjs +0 -69
- package/bin/subagent-parent-responsiveness.cjs +0 -19
- package/bin/subagent-skill-policy.cjs +0 -206
- package/bin/subagent-timeout-policy.cjs +0 -182
- package/bin/subagent-tool-policy.cjs +0 -60
- package/bin/subagent-usage-rollup-policy.cjs +0 -29
- package/bin/system-prompt-context-policy.cjs +0 -124
- package/bin/system-prompt-token-cache-policy.cjs +0 -60
- package/bin/telegram-addressed-focus.cjs +0 -55
- package/bin/telegram-addressed-priority.cjs +0 -12
- package/bin/telegram-approval-relay.cjs +0 -290
- package/bin/telegram-bot-priority.cjs +0 -17
- package/bin/telegram-console-status-policy.cjs +0 -174
- package/bin/telegram-context-projection-policy.cjs +0 -141
- package/bin/telegram-delivery-lifecycle.cjs +0 -125
- package/bin/telegram-direct-focus-policy.cjs +0 -273
- package/bin/telegram-mcp-compatibility.cjs +0 -49
- package/bin/telegram-media-delivery-policy.cjs +0 -42
- package/bin/telegram-private-conversation-policy.cjs +0 -185
- package/bin/telegram-queue-handoff-policy.cjs +0 -73
- package/bin/telegram-remote-status-policy.cjs +0 -120
- package/bin/telegram-session-queue-runtime.mjs +0 -306
- package/bin/telegram-text-chunk-policy.cjs +0 -63
- package/bin/telegram-truncated-reply-policy.cjs +0 -37
- package/bin/telegram-urgent-policy.cjs +0 -45
- package/bin/telemetry-spool-policy.cjs +0 -57
- package/bin/thinking-activity-status-policy.cjs +0 -132
- package/bin/thinking-only-guard.cjs +0 -79
- package/bin/todo-list-turn-policy.cjs +0 -131
- package/bin/tool-call-loop-policy.cjs +0 -51
- package/bin/tool-file-persistence.cjs +0 -141
- package/bin/tool-result-offload-policy.cjs +0 -359
- package/bin/tool-result-offload-telemetry.cjs +0 -12
- package/bin/tool-schema-token-cache-policy.cjs +0 -41
- package/bin/tool-stream-preview-policy.cjs +0 -9
- package/bin/tui-functional-contract.cjs +0 -55
- package/bin/turn-tool-performance-policy.cjs +0 -486
- package/bin/usage-cache-efficiency-policy.cjs +0 -26
- package/bin/user-home-path-policy.cjs +0 -13
- package/bin/user-message-offload-policy.cjs +0 -103
- package/bin/user-prompt-hook-origin-policy.cjs +0 -34
- package/bin/user-tool-record-policy.cjs +0 -7
- package/bin/validated-learning-insight-policy.cjs +0 -58
- package/bin/validated-learning-outcome-trace.cjs +0 -107
- package/bin/validated-learning-performance-policy.cjs +0 -53
- package/bin/validated-learning-signal.cjs +0 -463
- package/bin/windows-bash-dialect-policy.cjs +0 -25
- package/bin/windows-node-crash-dump.cjs +0 -110
- package/bin/write-continuation-policy.cjs +0 -69
- package/codebase-index/README.md +0 -82
- package/codebase-index/codebase_index.py +0 -470
- package/standard-skills/agent-browser/SKILL.md +0 -19
- package/standard-skills/agent-browser/references/runtime.md +0 -8
- package/standard-skills/blun-session-inspector/SKILL.md +0 -41
- package/standard-skills/blun-session-inspector/scripts/inspect-session.cjs +0 -437
- package/standard-skills/design-taste-frontend/SKILL.md +0 -1206
- package/standard-skills/full-output-enforcement/SKILL.md +0 -49
- package/standard-skills/high-end-visual-design/SKILL.md +0 -98
- package/standard-skills/image-to-code/SKILL.md +0 -1228
- package/standard-skills/industrial-brutalist-ui/SKILL.md +0 -92
- package/standard-skills/minimalist-ui/SKILL.md +0 -85
- package/standard-skills/motion-design-taste/SKILL.md +0 -74
- package/standard-skills/playwright-testing/SKILL.md +0 -19
- package/standard-skills/playwright-testing/references/runtime.md +0 -7
- package/standard-skills/premortem/SKILL.md +0 -148
- package/standard-skills/redesign-existing-projects/SKILL.md +0 -178
- package/standard-skills/research-evidence/SKILL.md +0 -39
- package/standard-skills/research-evidence/references/evidence-format.md +0 -104
- package/standard-skills/research-evidence/scripts/evidence-collection.cjs +0 -260
- package/standard-skills/research-evidence/scripts/score-report.cjs +0 -130
- package/standard-skills/screenshot-lesen/SKILL.md +0 -52
- package/standard-skills/stitch-design-taste/DESIGN.md +0 -121
- package/standard-skills/stitch-design-taste/SKILL.md +0 -184
- package/standard-skills/telegram-channel/SKILL.md +0 -18
- package/standard-skills/telegram-channel/references/runtime.md +0 -7
- package/standard-skills/venture-flywheel/SKILL.md +0 -32
- package/standard-skills/venture-flywheel/identity/project-identity.cjs +0 -146
- package/standard-skills/venture-flywheel/policy/capability-engine.cjs +0 -114
- package/standard-skills/venture-flywheel/policy/repository-trust.cjs +0 -229
- package/standard-skills/venture-flywheel/references/BEISPIELE-phase0.md +0 -146
- package/standard-skills/venture-flywheel/references/CAPABILITY-MAP.md +0 -34
- package/standard-skills/venture-flywheel/references/SPEC-phase0-identity-trust.md +0 -77
- package/standard-skills/venture-flywheel/references/SPEC-phase0-state-events.md +0 -93
- package/standard-skills/venture-flywheel/schemas/capability-decision.schema.json +0 -13
- package/standard-skills/venture-flywheel/schemas/execution-event.schema.json +0 -44
- package/standard-skills/venture-flywheel/schemas/project-identity.schema.json +0 -32
- package/standard-skills/venture-flywheel/schemas/repository-trust.schema.json +0 -57
- package/standard-skills/venture-flywheel/schemas/run-transition.schema.json +0 -59
- package/standard-skills/venture-flywheel/state/execution-event.cjs +0 -191
- package/standard-skills/venture-flywheel/state/task-state-machine.cjs +0 -190
- package/standard-skills/web-lesen/SKILL.md +0 -73
- package/standard-skills/web-lesen/scripts/crawl_public.py +0 -379
- package/standard-skills/windows-mcp/SKILL.md +0 -19
- package/standard-skills/windows-mcp/references/runtime.md +0 -9
- package/telegram-plugin/DELIVERY.md +0 -36
- package/telegram-plugin/bin/telegram-approval-relay.cjs +0 -290
- package/telegram-plugin/bin/telegram-console-status-policy.cjs +0 -175
- package/telegram-plugin/bin/telegram-delivery-lifecycle.cjs +0 -125
- package/telegram-plugin/bin/telegram-direct-reply-policy.cjs +0 -48
- package/telegram-plugin/bin/telegram-launcher-status-queue.cjs +0 -122
- package/telegram-plugin/bin/telegram-private-conversation-policy.cjs +0 -186
- package/telegram-plugin/bin/telegram-remote-status-policy.cjs +0 -121
- package/telegram-plugin/bin/telegram-reply-parts.cjs +0 -149
- package/telegram-plugin/bin/telegram-text-chunk-policy.cjs +0 -63
- package/telegram-plugin/bin/telegram-typing-keepalive.cjs +0 -89
- package/telegram-plugin/compat/mcp-server-fa511cd1.mjs +0 -73825
- /package/{bin → scripts}/fix-node-pty-perms.js +0 -0
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const crypto = require('node:crypto');
|
|
4
|
-
const fs = require('node:fs');
|
|
5
|
-
const os = require('node:os');
|
|
6
|
-
const path = require('node:path');
|
|
7
|
-
const { personalityContextEnabled } = require('./personality-mode.cjs');
|
|
8
|
-
|
|
9
|
-
const SAFE_ID_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/u;
|
|
10
|
-
const ALLOWED_KINDS = new Set(['first_interaction']);
|
|
11
|
-
|
|
12
|
-
function enabled(env) {
|
|
13
|
-
const configured = String(env.BLUN_IDENTITY_JOURNAL ?? '').trim();
|
|
14
|
-
if (configured) return /^(?:1|true)$/iu.test(configured);
|
|
15
|
-
return personalityContextEnabled(env);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function safeId(value) {
|
|
19
|
-
const normalized = String(value ?? '').trim();
|
|
20
|
-
return SAFE_ID_RE.test(normalized) ? normalized : '';
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function isInside(parent, child) {
|
|
24
|
-
const relative = path.relative(parent, child);
|
|
25
|
-
return relative === '' || (!relative.startsWith(`..${path.sep}`) && relative !== '..' && !path.isAbsolute(relative));
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function resolvedRoot(env) {
|
|
29
|
-
const configuredHome = String(env.BLUN_SHARED_HOME ?? env.BLUN_HOME ?? '').trim();
|
|
30
|
-
const home = path.resolve(configuredHome || path.join(os.homedir(), '.blun'));
|
|
31
|
-
const configuredRoot = String(env.BLUN_IDENTITY_ROOT ?? '').trim();
|
|
32
|
-
const root = path.resolve(configuredRoot || path.join(home, 'identity'));
|
|
33
|
-
if (!isInside(home, root)) return '';
|
|
34
|
-
try {
|
|
35
|
-
if (fs.lstatSync(root).isSymbolicLink()) return '';
|
|
36
|
-
const realHome = fs.realpathSync(home);
|
|
37
|
-
const realRoot = fs.realpathSync(root);
|
|
38
|
-
return isInside(realHome, realRoot) ? realRoot : '';
|
|
39
|
-
} catch {
|
|
40
|
-
return '';
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function trustedTimestamp(value) {
|
|
45
|
-
const text = String(value ?? '').trim();
|
|
46
|
-
if (!text || text.length > 64 || Number.isNaN(Date.parse(text))) return '';
|
|
47
|
-
return text;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function createJsonOnce(root, target, value) {
|
|
51
|
-
if (!isInside(root, target)) return false;
|
|
52
|
-
let handle;
|
|
53
|
-
try {
|
|
54
|
-
const parent = path.dirname(target);
|
|
55
|
-
fs.mkdirSync(parent, { recursive: true });
|
|
56
|
-
if (!isInside(root, fs.realpathSync(parent))) return false;
|
|
57
|
-
handle = fs.openSync(target, 'wx', 0o600);
|
|
58
|
-
fs.writeFileSync(handle, `${JSON.stringify(value, null, 2)}\n`, 'utf8');
|
|
59
|
-
fs.fsyncSync(handle);
|
|
60
|
-
return true;
|
|
61
|
-
} catch {
|
|
62
|
-
return false;
|
|
63
|
-
} finally {
|
|
64
|
-
if (handle !== undefined) fs.closeSync(handle);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function recordIdentityJournalCandidate(signal, env = process.env) {
|
|
69
|
-
if (!enabled(env) || !signal || typeof signal !== 'object') return undefined;
|
|
70
|
-
const kind = String(signal.kind ?? '').trim();
|
|
71
|
-
const tenantId = safeId(signal.tenant_id);
|
|
72
|
-
const configuredTenantId = safeId(env.BLUN_IDENTITY_TENANT_ID);
|
|
73
|
-
const agentId = safeId(signal.agent_id);
|
|
74
|
-
const configuredAgentId = safeId(env.BLUN_AGENT_ID);
|
|
75
|
-
const actorId = safeId(signal.actor_id);
|
|
76
|
-
const groupId = safeId(signal.group_id);
|
|
77
|
-
const occurredAt = trustedTimestamp(signal.occurred_at);
|
|
78
|
-
if (!ALLOWED_KINDS.has(kind)
|
|
79
|
-
|| !tenantId || tenantId !== configuredTenantId
|
|
80
|
-
|| !agentId || agentId !== configuredAgentId
|
|
81
|
-
|| !actorId || !occurredAt
|
|
82
|
-
|| (signal.group_id !== undefined && !groupId)) return undefined;
|
|
83
|
-
|
|
84
|
-
const root = resolvedRoot(env);
|
|
85
|
-
if (!root) return undefined;
|
|
86
|
-
const identity = [kind, tenantId, agentId, actorId, groupId, occurredAt].join('\0');
|
|
87
|
-
const candidateId = crypto.createHash('sha256').update(identity).digest('hex').slice(0, 32);
|
|
88
|
-
const target = path.resolve(root, 'agents', agentId, 'journal', 'candidates', `${candidateId}.json`);
|
|
89
|
-
const value = {
|
|
90
|
-
version: 1,
|
|
91
|
-
candidate_id: candidateId,
|
|
92
|
-
status: 'pending',
|
|
93
|
-
kind,
|
|
94
|
-
tenant_id: tenantId,
|
|
95
|
-
agent_id: agentId,
|
|
96
|
-
actor_id: actorId,
|
|
97
|
-
...(groupId ? { group_id: groupId } : {}),
|
|
98
|
-
occurred_at: occurredAt,
|
|
99
|
-
source: 'trusted_channel_metadata',
|
|
100
|
-
};
|
|
101
|
-
return {
|
|
102
|
-
candidate_id: candidateId,
|
|
103
|
-
created: createJsonOnce(root, target, value),
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
module.exports = { recordIdentityJournalCandidate };
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const crypto = require('node:crypto');
|
|
4
|
-
const fs = require('node:fs/promises');
|
|
5
|
-
const path = require('node:path');
|
|
6
|
-
|
|
7
|
-
const MAX_INPUT_DRAFT_BYTES = 64 * 1024;
|
|
8
|
-
// JSON may encode one accepted control byte as a six-byte Unicode escape.
|
|
9
|
-
const MAX_INPUT_DRAFT_FILE_BYTES = MAX_INPUT_DRAFT_BYTES * 6 + 1024;
|
|
10
|
-
const SCHEMA_VERSION = 1;
|
|
11
|
-
const VALID_MODES = new Set(['bash', 'prompt']);
|
|
12
|
-
|
|
13
|
-
function normalizeInputDraft(value) {
|
|
14
|
-
if (!value || typeof value !== 'object') return null;
|
|
15
|
-
if (!VALID_MODES.has(value.mode) || typeof value.text !== 'string') return null;
|
|
16
|
-
if (value.text.length === 0) return null;
|
|
17
|
-
if (Buffer.byteLength(value.text, 'utf8') > MAX_INPUT_DRAFT_BYTES) return null;
|
|
18
|
-
return { mode: value.mode, text: value.text };
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
async function clearInputDraft(filePath) {
|
|
22
|
-
await fs.rm(path.resolve(filePath), { force: true });
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
async function readInputDraft(filePath) {
|
|
26
|
-
const target = path.resolve(filePath);
|
|
27
|
-
try {
|
|
28
|
-
const stat = await fs.lstat(target);
|
|
29
|
-
if (!stat.isFile() || stat.isSymbolicLink() || stat.size > MAX_INPUT_DRAFT_FILE_BYTES) return null;
|
|
30
|
-
const record = JSON.parse(await fs.readFile(target, 'utf8'));
|
|
31
|
-
if (record?.schemaVersion !== SCHEMA_VERSION) return null;
|
|
32
|
-
return normalizeInputDraft(record);
|
|
33
|
-
} catch {
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
async function writeInputDraft(filePath, value) {
|
|
39
|
-
const target = path.resolve(filePath);
|
|
40
|
-
const text = typeof value?.text === 'string' ? value.text : '';
|
|
41
|
-
if (Buffer.byteLength(text, 'utf8') > MAX_INPUT_DRAFT_BYTES) {
|
|
42
|
-
throw new Error('draft_too_large');
|
|
43
|
-
}
|
|
44
|
-
if (text.length === 0) {
|
|
45
|
-
await clearInputDraft(target);
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
const draft = normalizeInputDraft(value);
|
|
49
|
-
if (draft === null) throw new Error('draft_invalid');
|
|
50
|
-
|
|
51
|
-
const directory = path.dirname(target);
|
|
52
|
-
const temporary = path.join(
|
|
53
|
-
directory,
|
|
54
|
-
`.${path.basename(target)}.${process.pid}.${crypto.randomUUID()}.tmp`,
|
|
55
|
-
);
|
|
56
|
-
await fs.mkdir(directory, { recursive: true, mode: 0o700 });
|
|
57
|
-
try {
|
|
58
|
-
await fs.writeFile(
|
|
59
|
-
temporary,
|
|
60
|
-
`${JSON.stringify({ schemaVersion: SCHEMA_VERSION, ...draft })}\n`,
|
|
61
|
-
{ encoding: 'utf8', flag: 'wx', mode: 0o600 },
|
|
62
|
-
);
|
|
63
|
-
await fs.rename(temporary, target);
|
|
64
|
-
await fs.chmod(target, 0o600).catch(() => {});
|
|
65
|
-
} catch (error) {
|
|
66
|
-
await fs.rm(temporary, { force: true }).catch(() => {});
|
|
67
|
-
throw error;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
module.exports = {
|
|
72
|
-
MAX_INPUT_DRAFT_BYTES,
|
|
73
|
-
clearInputDraft,
|
|
74
|
-
normalizeInputDraft,
|
|
75
|
-
readInputDraft,
|
|
76
|
-
writeInputDraft,
|
|
77
|
-
};
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"schema": "blun.king-tui-function-contract/v2",
|
|
3
|
-
"source": "FUNKTIONSLISTE-KING-TUI-ENTWURF-angel.md",
|
|
4
|
-
"items": [
|
|
5
|
-
{ "id": "1", "name": "live-output-tokens", "status": "unchanged-measured", "probe": "scripts/live-main-output-token-usage.test.cjs", "probeCase": "usage.record updates active-turn output" },
|
|
6
|
-
{ "id": "2", "name": "context-bar", "status": "fixed", "probe": "scripts/king-tui-visual-state.test.cjs", "probeCase": "173 percent renders numbers and critical color" },
|
|
7
|
-
{ "id": "3", "name": "compaction-bar-falls", "status": "fixed", "probe": "scripts/tui-state-contract.test.cjs", "probeCase": "remaining context falls while compaction runs" },
|
|
8
|
-
{ "id": "4", "name": "compaction-failure-visible", "status": "fixed", "probe": "scripts/tui-state-contract.test.cjs", "probeCase": "second session failure exposes reason and action" },
|
|
9
|
-
{ "id": "5", "name": "footer-profile-persona-version", "status": "fixed", "probe": "scripts/footer-version-quota-line.test.cjs", "probeCase": "rendered footer keeps the mode visible and moves the version to the quota line at 80 and 120 columns" },
|
|
10
|
-
{ "id": "6", "name": "escape-clears-queue", "status": "fixed", "probe": "scripts/tui-state-contract.test.cjs", "probeCase": "active visible and in-flight queues are cleared" },
|
|
11
|
-
{ "id": "7", "name": "slash-command-delivery", "status": "fixed", "probe": "scripts/tui-state-contract.test.cjs", "probeCase": "destructive commands defer during active turn; others run immediately" },
|
|
12
|
-
{ "id": "8", "name": "active-steer-safe-point", "status": "unchanged-measured", "probe": "scripts/active-steer-priority.test.cjs", "probeCase": "active steer wins next safe action" },
|
|
13
|
-
{ "id": "9", "name": "manual-compaction-bounded", "status": "unchanged-measured", "probe": "scripts/check-harness-555-regression.js", "probeCase": "manual compaction rejects history above request window" },
|
|
14
|
-
{ "id": "9a", "name": "ctrl-s-flushes-queued-input", "status": "unchanged-measured", "probe": "scripts/check-slash-escape-regression.js", "probeCase": "Ctrl+S flushes a queued slash draft" },
|
|
15
|
-
{ "id": "9b", "name": "post-compaction-context-recomputed", "status": "fixed", "probe": "scripts/tui-state-contract.test.cjs", "probeCase": "post-compaction remaining tokens replace pre-compaction value" },
|
|
16
|
-
{ "id": "10", "name": "proactive-compaction", "status": "unchanged-measured", "probe": "scripts/check-proactive-compaction-selected-tools-regression.js", "probeCase": "fixed in 568c7: 91 percent starts compaction while 89 percent does not" },
|
|
17
|
-
{ "id": "11", "name": "hierarchical-compaction", "status": "unchanged-measured", "probe": "scripts/king-tui-hierarchical-compaction.test.cjs", "probeCase": "oldest balanced segment stays below request window" },
|
|
18
|
-
{ "id": "12", "name": "second-compaction-failure-stops", "status": "fixed", "probe": "scripts/session-compaction-runtime.test.cjs", "probeCase": "failure count persists across turn reset and stops at two" },
|
|
19
|
-
{ "id": "13", "name": "resume-reloads-session", "status": "unchanged-measured", "probe": "scripts/check-resume-replay-regression.js", "probeCase": "resume replays a saved session with bounded history" },
|
|
20
|
-
{ "id": "14", "name": "cron-compaction-guard", "status": "fixed", "probe": "scripts/scoped-cron-run-runtime.test.cjs", "probeCase": "stopped compaction rejects cron; coalesced count warns group" },
|
|
21
|
-
{ "id": "15", "name": "launcher-restart-budget", "status": "fixed", "probe": "scripts/launcher-restart-budget.test.cjs", "probeCase": "four loaded-core failures restart only three times per rolling hour and enqueue one group line per decision" },
|
|
22
|
-
{ "id": "16", "name": "runtime-exit-last-tool", "status": "unchanged-measured", "probe": "scripts/runtime-exit-ledger-last-tool.test.cjs", "probeCase": "fixed in 568c7: exit record persists last observed tool" },
|
|
23
|
-
{ "id": "17", "name": "shell-after-tool-result", "status": "unchanged-measured", "probe": "scripts/check-shell-terminal-isolation-regression.js", "probeCase": "shell remains isolated after tool result" },
|
|
24
|
-
{ "id": "18", "name": "hook-under-100ms", "status": "fixed", "probe": "scripts/agent-spine-hook-latency.test.mjs", "probeCase": "slow hub queues durably in under 100 ms and drains later" },
|
|
25
|
-
{ "id": "19", "name": "agentspine-source-budget", "status": "fixed", "probe": "scripts/agent-spine-source-budget-behavior.test.mjs", "probeCase": "package boundary skips nested tree; 241 root files fail with action" },
|
|
26
|
-
{ "id": "20", "name": "windows-crash-dump", "status": "fixed", "probe": "scripts/windows-node-crash-dump.test.cjs", "probeCase": "Windows core bootstrap registers node.exe WER minidumps and writes a synchronous diagnostic report before exit" },
|
|
27
|
-
{ "id": "21", "name": "mcp-inventory", "status": "unchanged-measured", "probe": "scripts/check-active-profile-plugin-startup.js", "probeCase": "startup inventory reports connected servers and tool counts" },
|
|
28
|
-
{ "id": "22", "name": "telegram-group-and-dm", "status": "unchanged-measured", "probe": "scripts/check-telegram-direct-work-resume-regression.js", "probeCase": "group and direct messages enter the active session" },
|
|
29
|
-
{ "id": "23", "name": "goal-worker-contract", "status": "unchanged-measured", "probe": "scripts/agentspine-king-three-tick-e2e.test.mjs", "probeCase": "three checkpointed ticks complete one bound goal" },
|
|
30
|
-
{ "id": "24", "name": "task-list-and-queue", "status": "unchanged-measured", "probe": "scripts/check-todo-progress-regression.js", "probeCase": "active task and queued work update together" },
|
|
31
|
-
{ "id": "25", "name": "agentspine-and-premortem", "status": "unchanged-measured", "probe": "scripts/king-tui-premortem-command.test.cjs", "probeCase": "premortem command creates the measured analysis turn" }
|
|
32
|
-
]
|
|
33
|
-
}
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const crypto = require('node:crypto');
|
|
4
|
-
const fs = require('node:fs');
|
|
5
|
-
const path = require('node:path');
|
|
6
|
-
|
|
7
|
-
const RESTART_WINDOW_MS = 60 * 60 * 1000;
|
|
8
|
-
const MAX_RESTARTS_PER_WINDOW = 3;
|
|
9
|
-
const RESTART_DELAYS_MS = Object.freeze([1000, 3000, 5000]);
|
|
10
|
-
const INTENTIONAL_STOP_TTL_MS = 2 * 60 * 1000;
|
|
11
|
-
const WINDOWS_FAIL_FAST_MIN = 0xC0000000;
|
|
12
|
-
const WINDOWS_CONTROL_C_EXIT = 0xC000013A;
|
|
13
|
-
const OPERATOR_SIGNALS = new Set(['SIGHUP', 'SIGINT', 'SIGTERM']);
|
|
14
|
-
|
|
15
|
-
function restartBudgetPath(homeDir) {
|
|
16
|
-
return path.join(path.resolve(homeDir), 'diagnostics', 'launcher-restart-budget.json');
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function launcherStatusQueuePath(homeDir, stateDir) {
|
|
20
|
-
return stateDir
|
|
21
|
-
? path.join(path.resolve(stateDir), 'launcher-status-queue.jsonl')
|
|
22
|
-
: path.join(path.resolve(homeDir), 'channels', 'telegram', 'launcher-status-queue.jsonl');
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function intentionalStopMarkerPath(homeDir) {
|
|
26
|
-
return path.join(path.resolve(homeDir), 'diagnostics', 'intentional-core-stop.json');
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function readRestartAttempts(filePath, nowMs, fsImpl = fs) {
|
|
30
|
-
let parsed;
|
|
31
|
-
try { parsed = JSON.parse(fsImpl.readFileSync(filePath, 'utf8')); } catch { return []; }
|
|
32
|
-
if (parsed?.schema !== 'blun.launcher-restart-budget/v1' || !Array.isArray(parsed.attempts)) return [];
|
|
33
|
-
const minimum = nowMs - RESTART_WINDOW_MS;
|
|
34
|
-
return parsed.attempts.filter((value) => Number.isFinite(value) && value > minimum && value <= nowMs);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function atomicWriteJson(filePath, value, fsImpl = fs) {
|
|
38
|
-
fsImpl.mkdirSync(path.dirname(filePath), { recursive: true, mode: 0o700 });
|
|
39
|
-
const temporary = `${filePath}.${process.pid}.${crypto.randomUUID()}.tmp`;
|
|
40
|
-
try {
|
|
41
|
-
fsImpl.writeFileSync(temporary, `${JSON.stringify(value)}\n`, { encoding: 'utf8', mode: 0o600 });
|
|
42
|
-
fsImpl.renameSync(temporary, filePath);
|
|
43
|
-
} finally {
|
|
44
|
-
try { fsImpl.rmSync(temporary, { force: true }); } catch {}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function claimLauncherRestart(options) {
|
|
49
|
-
const nowMs = Number.isFinite(options.nowMs) ? options.nowMs : Date.now();
|
|
50
|
-
const filePath = restartBudgetPath(options.homeDir);
|
|
51
|
-
const attempts = readRestartAttempts(filePath, nowMs, options.fsImpl);
|
|
52
|
-
if (attempts.length >= MAX_RESTARTS_PER_WINDOW) {
|
|
53
|
-
return { allowed: false, attempt: attempts.length, limit: MAX_RESTARTS_PER_WINDOW, windowMs: RESTART_WINDOW_MS };
|
|
54
|
-
}
|
|
55
|
-
attempts.push(nowMs);
|
|
56
|
-
atomicWriteJson(filePath, {
|
|
57
|
-
schema: 'blun.launcher-restart-budget/v1',
|
|
58
|
-
updatedAt: new Date(nowMs).toISOString(),
|
|
59
|
-
attempts,
|
|
60
|
-
}, options.fsImpl);
|
|
61
|
-
return { allowed: true, attempt: attempts.length, limit: MAX_RESTARTS_PER_WINDOW, windowMs: RESTART_WINDOW_MS };
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function isWindowsFailFastExitCode(code) {
|
|
65
|
-
if (!Number.isInteger(code)) return false;
|
|
66
|
-
const unsigned = code >>> 0;
|
|
67
|
-
return unsigned >= WINDOWS_FAIL_FAST_MIN && unsigned !== WINDOWS_CONTROL_C_EXIT;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function isAbnormalCoreExit(result, loaded) {
|
|
71
|
-
if (result?.error) return true;
|
|
72
|
-
if (loaded !== true) return false;
|
|
73
|
-
if (OPERATOR_SIGNALS.has(result?.signal)) return false;
|
|
74
|
-
return isWindowsFailFastExitCode(result?.code);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function writeIntentionalStopMarker(options) {
|
|
78
|
-
const nowMs = Number.isFinite(options.nowMs) ? options.nowMs : Date.now();
|
|
79
|
-
const filePath = intentionalStopMarkerPath(options.homeDir);
|
|
80
|
-
atomicWriteJson(filePath, {
|
|
81
|
-
schema: 'blun.intentional-core-stop/v1',
|
|
82
|
-
pid: options.pid,
|
|
83
|
-
createdAtMs: nowMs,
|
|
84
|
-
expiresAtMs: nowMs + INTENTIONAL_STOP_TTL_MS,
|
|
85
|
-
}, options.fsImpl);
|
|
86
|
-
return filePath;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function consumeIntentionalStopMarker(options) {
|
|
90
|
-
const nowMs = Number.isFinite(options.nowMs) ? options.nowMs : Date.now();
|
|
91
|
-
const filePath = intentionalStopMarkerPath(options.homeDir);
|
|
92
|
-
const fsImpl = options.fsImpl || fs;
|
|
93
|
-
let marker;
|
|
94
|
-
try { marker = JSON.parse(fsImpl.readFileSync(filePath, 'utf8')); } catch { return false; }
|
|
95
|
-
try { fsImpl.rmSync(filePath, { force: true }); } catch {}
|
|
96
|
-
return marker?.schema === 'blun.intentional-core-stop/v1'
|
|
97
|
-
&& Number.isInteger(marker.pid)
|
|
98
|
-
&& marker.pid === options.childPid
|
|
99
|
-
&& Number.isFinite(marker.createdAtMs)
|
|
100
|
-
&& Number.isFinite(marker.expiresAtMs)
|
|
101
|
-
&& marker.createdAtMs <= nowMs
|
|
102
|
-
&& marker.expiresAtMs >= nowMs
|
|
103
|
-
&& marker.expiresAtMs - marker.createdAtMs <= INTENTIONAL_STOP_TTL_MS;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
function restartDelayMs(attempt) {
|
|
107
|
-
return RESTART_DELAYS_MS[Math.max(0, Math.min(RESTART_DELAYS_MS.length - 1, attempt - 1))];
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
function appendLauncherStatus(options) {
|
|
111
|
-
const nowMs = Number.isFinite(options.nowMs) ? options.nowMs : Date.now();
|
|
112
|
-
const exhausted = options.kind === 'launcher-restart-exhausted';
|
|
113
|
-
const signal = options.signal ? ` signal=${options.signal}` : '';
|
|
114
|
-
const text = exhausted
|
|
115
|
-
? `[launcher.restart] stopped ${options.attempt}/${options.limit} exit=${options.exitCode}${signal}`
|
|
116
|
-
: `[launcher.restart] ${options.attempt}/${options.limit} exit=${options.exitCode}${signal}`;
|
|
117
|
-
const event = {
|
|
118
|
-
schema: 'blun.launcher-status/v1',
|
|
119
|
-
id: crypto.randomUUID(),
|
|
120
|
-
createdAt: new Date(nowMs).toISOString(),
|
|
121
|
-
kind: options.kind,
|
|
122
|
-
attempt: options.attempt,
|
|
123
|
-
limit: options.limit,
|
|
124
|
-
exitCode: options.exitCode,
|
|
125
|
-
...(options.signal ? { signal: options.signal } : {}),
|
|
126
|
-
text,
|
|
127
|
-
};
|
|
128
|
-
const filePath = launcherStatusQueuePath(options.homeDir, options.stateDir);
|
|
129
|
-
const fsImpl = options.fsImpl || fs;
|
|
130
|
-
fsImpl.mkdirSync(path.dirname(filePath), { recursive: true, mode: 0o700 });
|
|
131
|
-
fsImpl.appendFileSync(filePath, `${JSON.stringify(event)}\n`, { encoding: 'utf8', mode: 0o600 });
|
|
132
|
-
return event;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
module.exports = {
|
|
136
|
-
INTENTIONAL_STOP_TTL_MS,
|
|
137
|
-
MAX_RESTARTS_PER_WINDOW,
|
|
138
|
-
RESTART_DELAYS_MS,
|
|
139
|
-
RESTART_WINDOW_MS,
|
|
140
|
-
appendLauncherStatus,
|
|
141
|
-
claimLauncherRestart,
|
|
142
|
-
consumeIntentionalStopMarker,
|
|
143
|
-
intentionalStopMarkerPath,
|
|
144
|
-
isAbnormalCoreExit,
|
|
145
|
-
isWindowsFailFastExitCode,
|
|
146
|
-
launcherStatusQueuePath,
|
|
147
|
-
restartBudgetPath,
|
|
148
|
-
restartDelayMs,
|
|
149
|
-
writeIntentionalStopMarker,
|
|
150
|
-
};
|
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const DEFAULT_MIN_WORDS = 320;
|
|
4
|
-
const DEFAULT_WINDOW_WORDS = 20;
|
|
5
|
-
const DEFAULT_REQUIRED_OCCURRENCES = 4;
|
|
6
|
-
const DEFAULT_MAX_CHARS = 24_000;
|
|
7
|
-
const DEFAULT_CHECK_EVERY_WORDS = 24;
|
|
8
|
-
const DEFAULT_SHORT_BURST_MAX_WORDS = 8;
|
|
9
|
-
const DEFAULT_SHORT_BURST_MIN_OCCURRENCES = 8;
|
|
10
|
-
const DEFAULT_SHORT_BURST_MIN_TOTAL_WORDS = 24;
|
|
11
|
-
const DEFAULT_SHORT_BURST_MIN_WORDS = 2;
|
|
12
|
-
const DEFAULT_SHORT_BURST_SCAN_WORDS = 192;
|
|
13
|
-
|
|
14
|
-
function normalizeWords(text) {
|
|
15
|
-
return String(text)
|
|
16
|
-
.normalize('NFKC')
|
|
17
|
-
.toLocaleLowerCase('de-DE')
|
|
18
|
-
.match(/[\p{L}\p{N}_]+/gu) ?? [];
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function repeatedWindow(words, options) {
|
|
22
|
-
const {
|
|
23
|
-
windowWords,
|
|
24
|
-
requiredOccurrences,
|
|
25
|
-
} = options;
|
|
26
|
-
const seen = new Map();
|
|
27
|
-
|
|
28
|
-
for (let index = 0; index + windowWords <= words.length; index += 1) {
|
|
29
|
-
const window = words.slice(index, index + windowWords).join('\u0000');
|
|
30
|
-
const previous = seen.get(window);
|
|
31
|
-
if (previous === undefined) {
|
|
32
|
-
seen.set(window, { count: 1, lastIndex: index });
|
|
33
|
-
continue;
|
|
34
|
-
}
|
|
35
|
-
if (index - previous.lastIndex < windowWords) continue;
|
|
36
|
-
const count = previous.count + 1;
|
|
37
|
-
if (count >= requiredOccurrences) {
|
|
38
|
-
return {
|
|
39
|
-
count,
|
|
40
|
-
firstWords: words.slice(index, index + windowWords).join(' '),
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
seen.set(window, { count, lastIndex: index });
|
|
44
|
-
}
|
|
45
|
-
return null;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function equalWindow(words, left, right, width) {
|
|
49
|
-
for (let offset = 0; offset < width; offset += 1) {
|
|
50
|
-
if (words[left + offset] !== words[right + offset]) return false;
|
|
51
|
-
}
|
|
52
|
-
return true;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function canCloseConsecutiveWindow(words, minWords, maxWords) {
|
|
56
|
-
const lastIndex = words.length - 1;
|
|
57
|
-
for (let windowWords = minWords; windowWords <= maxWords; windowWords += 1) {
|
|
58
|
-
const previousIndex = lastIndex - windowWords;
|
|
59
|
-
if (previousIndex >= 0 && words[lastIndex] === words[previousIndex]) return true;
|
|
60
|
-
}
|
|
61
|
-
return false;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function repeatedConsecutiveWindow(words, options) {
|
|
65
|
-
const {
|
|
66
|
-
maxWords,
|
|
67
|
-
minOccurrences,
|
|
68
|
-
minTotalWords,
|
|
69
|
-
minWords,
|
|
70
|
-
scanWords,
|
|
71
|
-
firstEnd = 1,
|
|
72
|
-
} = options;
|
|
73
|
-
const sourceStart = Math.max(0, words.length - scanWords);
|
|
74
|
-
const localFirstEnd = Math.max(sourceStart + 1, firstEnd);
|
|
75
|
-
|
|
76
|
-
for (let end = localFirstEnd; end <= words.length; end += 1) {
|
|
77
|
-
for (let windowWords = minWords; windowWords <= maxWords; windowWords += 1) {
|
|
78
|
-
const requiredOccurrences = Math.max(
|
|
79
|
-
minOccurrences,
|
|
80
|
-
Math.ceil(minTotalWords / windowWords),
|
|
81
|
-
);
|
|
82
|
-
const requiredSpan = windowWords * requiredOccurrences;
|
|
83
|
-
const start = end - requiredSpan;
|
|
84
|
-
if (start < sourceStart) continue;
|
|
85
|
-
let count = 1;
|
|
86
|
-
let cursor = start + windowWords;
|
|
87
|
-
while (cursor + windowWords <= end
|
|
88
|
-
&& equalWindow(words, start, cursor, windowWords)) {
|
|
89
|
-
count += 1;
|
|
90
|
-
cursor += windowWords;
|
|
91
|
-
}
|
|
92
|
-
if (count < requiredOccurrences) continue;
|
|
93
|
-
return {
|
|
94
|
-
kind: 'short_burst',
|
|
95
|
-
count,
|
|
96
|
-
firstWords: words.slice(start, start + windowWords).join(' '),
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
return null;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function createLiveResponseRepetitionGuard(options = {}) {
|
|
104
|
-
const config = {
|
|
105
|
-
checkEveryWords: options.checkEveryWords ?? DEFAULT_CHECK_EVERY_WORDS,
|
|
106
|
-
maxChars: options.maxChars ?? DEFAULT_MAX_CHARS,
|
|
107
|
-
minWords: options.minWords ?? DEFAULT_MIN_WORDS,
|
|
108
|
-
requiredOccurrences: options.requiredOccurrences ?? DEFAULT_REQUIRED_OCCURRENCES,
|
|
109
|
-
shortBurstMaxWords: options.shortBurstMaxWords ?? DEFAULT_SHORT_BURST_MAX_WORDS,
|
|
110
|
-
shortBurstMinOccurrences: options.shortBurstMinOccurrences
|
|
111
|
-
?? DEFAULT_SHORT_BURST_MIN_OCCURRENCES,
|
|
112
|
-
shortBurstMinTotalWords: options.shortBurstMinTotalWords
|
|
113
|
-
?? DEFAULT_SHORT_BURST_MIN_TOTAL_WORDS,
|
|
114
|
-
shortBurstMinWords: options.shortBurstMinWords ?? DEFAULT_SHORT_BURST_MIN_WORDS,
|
|
115
|
-
shortBurstScanWords: options.shortBurstScanWords ?? DEFAULT_SHORT_BURST_SCAN_WORDS,
|
|
116
|
-
windowWords: options.windowWords ?? DEFAULT_WINDOW_WORDS,
|
|
117
|
-
};
|
|
118
|
-
let text = '';
|
|
119
|
-
let lastCheckedWords = 0;
|
|
120
|
-
let lastShortBurstLastWord = '';
|
|
121
|
-
let lastShortBurstWordCount = 0;
|
|
122
|
-
let detection = null;
|
|
123
|
-
|
|
124
|
-
return {
|
|
125
|
-
push(delta) {
|
|
126
|
-
if (detection !== null || typeof delta !== 'string' || delta.length === 0) return detection;
|
|
127
|
-
text = `${text}${delta}`.slice(-config.maxChars);
|
|
128
|
-
const words = normalizeWords(text);
|
|
129
|
-
const previousShortBurstWordCount = lastShortBurstWordCount;
|
|
130
|
-
const lastWord = words.at(-1) ?? '';
|
|
131
|
-
const wordCountChanged = words.length !== previousShortBurstWordCount;
|
|
132
|
-
const lastWordChanged = lastWord !== lastShortBurstLastWord;
|
|
133
|
-
const firstChangedEnd = words.length > lastShortBurstWordCount
|
|
134
|
-
? Math.max(1, lastShortBurstWordCount)
|
|
135
|
-
: words.length;
|
|
136
|
-
const shouldCheckShortBurst = wordCountChanged || (lastWordChanged
|
|
137
|
-
&& canCloseConsecutiveWindow(
|
|
138
|
-
words,
|
|
139
|
-
config.shortBurstMinWords,
|
|
140
|
-
config.shortBurstMaxWords,
|
|
141
|
-
));
|
|
142
|
-
lastShortBurstLastWord = lastWord;
|
|
143
|
-
lastShortBurstWordCount = words.length;
|
|
144
|
-
if (words.length >= config.shortBurstMinTotalWords && shouldCheckShortBurst) {
|
|
145
|
-
const shortBurst = repeatedConsecutiveWindow(words, {
|
|
146
|
-
firstEnd: firstChangedEnd,
|
|
147
|
-
maxWords: config.shortBurstMaxWords,
|
|
148
|
-
minOccurrences: config.shortBurstMinOccurrences,
|
|
149
|
-
minTotalWords: config.shortBurstMinTotalWords,
|
|
150
|
-
minWords: config.shortBurstMinWords,
|
|
151
|
-
scanWords: config.shortBurstScanWords,
|
|
152
|
-
});
|
|
153
|
-
if (shortBurst !== null) {
|
|
154
|
-
detection = {
|
|
155
|
-
...shortBurst,
|
|
156
|
-
charCount: text.length,
|
|
157
|
-
wordCount: words.length,
|
|
158
|
-
};
|
|
159
|
-
return detection;
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
if (words.length < config.minWords) return null;
|
|
163
|
-
if (words.length - lastCheckedWords < config.checkEveryWords) return null;
|
|
164
|
-
lastCheckedWords = words.length;
|
|
165
|
-
const repeated = repeatedWindow(words, config);
|
|
166
|
-
if (repeated === null) return null;
|
|
167
|
-
detection = {
|
|
168
|
-
kind: 'long_window',
|
|
169
|
-
...repeated,
|
|
170
|
-
charCount: text.length,
|
|
171
|
-
wordCount: words.length,
|
|
172
|
-
};
|
|
173
|
-
return detection;
|
|
174
|
-
},
|
|
175
|
-
result() {
|
|
176
|
-
return detection;
|
|
177
|
-
},
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
module.exports = {
|
|
182
|
-
DEFAULT_CHECK_EVERY_WORDS,
|
|
183
|
-
DEFAULT_MAX_CHARS,
|
|
184
|
-
DEFAULT_MIN_WORDS,
|
|
185
|
-
DEFAULT_REQUIRED_OCCURRENCES,
|
|
186
|
-
DEFAULT_SHORT_BURST_MAX_WORDS,
|
|
187
|
-
DEFAULT_SHORT_BURST_MIN_OCCURRENCES,
|
|
188
|
-
DEFAULT_SHORT_BURST_MIN_TOTAL_WORDS,
|
|
189
|
-
DEFAULT_SHORT_BURST_MIN_WORDS,
|
|
190
|
-
DEFAULT_SHORT_BURST_SCAN_WORDS,
|
|
191
|
-
DEFAULT_WINDOW_WORDS,
|
|
192
|
-
createLiveResponseRepetitionGuard,
|
|
193
|
-
normalizeWords,
|
|
194
|
-
repeatedConsecutiveWindow,
|
|
195
|
-
repeatedWindow,
|
|
196
|
-
};
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
function createLlmConfigChangeDetector(options = {}) {
|
|
4
|
-
const serializeParameters = options.serializeParameters ?? JSON.stringify;
|
|
5
|
-
if (typeof serializeParameters !== 'function') {
|
|
6
|
-
throw new TypeError('serializeParameters must be a function');
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
let previous;
|
|
10
|
-
|
|
11
|
-
return function shouldLogConfig(input) {
|
|
12
|
-
const tools = Array.isArray(input.tools) ? input.tools : [];
|
|
13
|
-
const sameScalars = previous !== undefined
|
|
14
|
-
&& previous.provider === input.provider
|
|
15
|
-
&& previous.model === input.model
|
|
16
|
-
&& previous.modelAlias === input.modelAlias
|
|
17
|
-
&& previous.thinkingEffort === input.thinkingEffort
|
|
18
|
-
&& previous.systemPrompt === input.systemPrompt;
|
|
19
|
-
|
|
20
|
-
if (sameScalars && previous.tools.length === tools.length) {
|
|
21
|
-
let exactToolMatch = true;
|
|
22
|
-
for (let index = 0; index < tools.length; index += 1) {
|
|
23
|
-
const tool = tools[index];
|
|
24
|
-
const prior = previous.tools[index];
|
|
25
|
-
if (
|
|
26
|
-
prior.tool !== tool
|
|
27
|
-
|| prior.name !== tool.name
|
|
28
|
-
|| prior.description !== tool.description
|
|
29
|
-
|| prior.parameters !== tool.parameters
|
|
30
|
-
) {
|
|
31
|
-
exactToolMatch = false;
|
|
32
|
-
break;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
if (exactToolMatch) return false;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
let toolsChanged = previous === undefined || previous.tools.length !== tools.length;
|
|
39
|
-
const toolSnapshot = tools.map((tool, index) => {
|
|
40
|
-
const prior = previous?.tools[index];
|
|
41
|
-
const parametersJson = prior?.parameters === tool.parameters
|
|
42
|
-
? prior.parametersJson
|
|
43
|
-
: serializeParameters(tool.parameters);
|
|
44
|
-
if (
|
|
45
|
-
prior === undefined
|
|
46
|
-
|| prior.name !== tool.name
|
|
47
|
-
|| prior.description !== tool.description
|
|
48
|
-
|| prior.parametersJson !== parametersJson
|
|
49
|
-
) {
|
|
50
|
-
toolsChanged = true;
|
|
51
|
-
}
|
|
52
|
-
return {
|
|
53
|
-
tool,
|
|
54
|
-
name: tool.name,
|
|
55
|
-
description: tool.description,
|
|
56
|
-
parameters: tool.parameters,
|
|
57
|
-
parametersJson,
|
|
58
|
-
};
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
const changed = !sameScalars || toolsChanged;
|
|
62
|
-
previous = {
|
|
63
|
-
provider: input.provider,
|
|
64
|
-
model: input.model,
|
|
65
|
-
modelAlias: input.modelAlias,
|
|
66
|
-
thinkingEffort: input.thinkingEffort,
|
|
67
|
-
systemPrompt: input.systemPrompt,
|
|
68
|
-
tools: toolSnapshot,
|
|
69
|
-
};
|
|
70
|
-
return changed;
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
module.exports = {
|
|
75
|
-
createLlmConfigChangeDetector,
|
|
76
|
-
};
|