@shundoo-ai/dsh-cosmic 1.0.19 → 1.0.21
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/cordis.patch.yml +5 -5
- package/package.json +1 -1
- package/skills/cosmic-build/CHANGELOG.md +4 -0
- package/skills/cosmic-build/LOCAL-PATCHES.md +91 -40
- package/skills/cosmic-build/SKILL.md +46 -13
- package/skills/cosmic-build/assets/platform-report-filters/TypedReportFilterFields.java +169 -0
- package/skills/cosmic-build/assets/platform-report-filters/platform.patch +98 -0
- package/skills/cosmic-build/assets/report-algo-benchmark/ReportAlgoBenchmark.java +48 -0
- package/skills/cosmic-build/assets/report-algo-benchmark/ReportBenchmarkLogFactory.java +7 -0
- package/skills/cosmic-build/examples/java-rules/CosmicEntryQuery.java +26 -0
- package/skills/cosmic-build/examples/java-rules/CosmicReportAggregation.java +35 -0
- package/skills/cosmic-build/examples/java-rules/CosmicReportFilters.java +77 -0
- package/skills/cosmic-build/examples/java-rules/CosmicTimeAdapter.java +25 -0
- package/skills/cosmic-build/examples/java-rules/CosmicTimeAdapterCheck.java +26 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/api/algo/GroupbyDataSet.md +47 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/api/entity/report/FilterInfo.md +12 -12
- package/skills/cosmic-build/knowledge/cosmic/platform/api/entity/report/FilterItemInfo.md +2 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/form-plugin.md +2 -4
- package/skills/cosmic-build/knowledge/cosmic/platform/java-type-contracts.md +11 -2
- package/skills/cosmic-build/knowledge/cosmic/platform/list-plugin.md +18 -14
- package/skills/cosmic-build/knowledge/cosmic/platform/operation-plugin.md +4 -4
- package/skills/cosmic-build/knowledge/cosmic/platform/reportlistdata-plugin.md +17 -9
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/operation/cross-entity-aggregate-writeback.md +2 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/operation/pre-post-operation.md +15 -7
- package/skills/cosmic-build/knowledge/cosmic/platform/sdk/sdk-algo.md +24 -68
- package/skills/cosmic-build/knowledge/cosmic/platform/workflow-plugin.md +2 -7
- package/skills/cosmic-build/references/application-context.md +35 -1
- package/skills/cosmic-build/references/common-reference.md +1 -1
- package/skills/cosmic-build/references/compile-guide.md +55 -68
- package/skills/cosmic-build/references/delivery.md +59 -7
- package/skills/cosmic-build/references/execution-contract.md +38 -0
- package/skills/cosmic-build/references/form-discovery.md +7 -1
- package/skills/cosmic-build/references/java-plugin-delivery.md +32 -162
- package/skills/cosmic-build/references/operation-dispatch.md +17 -0
- package/skills/cosmic-build/references/plugin-handoff-input.md +131 -0
- package/skills/cosmic-build/references/plugin-runtime-routing.md +1 -1
- package/skills/cosmic-build/references/report-filter-contract.md +78 -0
- package/skills/cosmic-build/references/sdk-inspection.md +23 -0
- package/skills/cosmic-build/schemas/data-model-authoring.schema.json +2 -3
- package/skills/cosmic-build/scripts/_http_client.py +55 -55
- package/skills/cosmic-build/scripts/appconfig_load.py +2 -2
- package/skills/cosmic-build/scripts/apply_report_filter_extension.py +39 -0
- package/skills/cosmic-build/scripts/bootstrap_cosmic_context.py +37 -2
- package/skills/cosmic-build/scripts/compile_plugin_source.py +279 -156
- package/skills/cosmic-build/scripts/execution_binding.py +40 -0
- package/skills/cosmic-build/scripts/inspect_platform_sdk.py +169 -0
- package/skills/cosmic-build/scripts/kd_api.py +23 -22
- package/skills/cosmic-build/scripts/kd_auth.py +1 -1
- package/skills/cosmic-build/scripts/kd_env_loader.py +19 -10
- package/skills/cosmic-build/scripts/kd_token_cache.py +2 -2
- package/skills/cosmic-build/scripts/kingscript_sdk_sync.py +350 -0
- package/skills/cosmic-build/scripts/kingscript_source_gate.py +11 -8
- package/skills/cosmic-build/scripts/platform_api_contract.py +246 -11
- package/skills/cosmic-build/scripts/plugin_corpus/build_index.py +403 -0
- package/skills/cosmic-build/scripts/plugin_corpus/jvm_classfile.py +281 -0
- package/skills/cosmic-build/scripts/plugin_corpus/measure_api_usage.py +446 -0
- package/skills/cosmic-build/scripts/plugin_source_gate.py +48 -7
- package/skills/cosmic-build/scripts/plugin_target_sdk.py +45 -0
- package/skills/cosmic-build/scripts/prepare_plugin_handoff.py +493 -47
- package/skills/cosmic-build/scripts/preview_url.py +35 -6
- package/skills/cosmic-build/scripts/query_plugin_handoff.py +250 -0
- package/skills/cosmic-build/scripts/register_plugins.py +28 -2
- package/skills/cosmic-build/scripts/render_output_cards.py +42 -9
- package/skills/cosmic-build/scripts/report_algo_benchmark.py +46 -0
- package/skills/cosmic-build/scripts/run.py +2 -2
- package/skills/cosmic-build/scripts/sync_generated_locale_assets.py +43 -0
- package/skills/cosmic-build/scripts/test/fixtures/ReportSdkCheck.java +64 -0
- package/skills/cosmic-build/scripts/test/fixtures/java_context_booking_native.json +541 -0
- package/skills/cosmic-build/scripts/test/test_add_rule_business_contract.py +85 -14
- package/skills/cosmic-build/scripts/test/test_batch5_drift_governance.py +12 -3
- package/skills/cosmic-build/scripts/test/test_build_meta_order.py +0 -16
- package/skills/cosmic-build/scripts/test/test_cli_continuation.py +87 -0
- package/skills/cosmic-build/scripts/test/test_compile_plugin_source.py +224 -3
- package/skills/cosmic-build/scripts/test/test_control_authoring.py +123 -4
- package/skills/cosmic-build/scripts/test/test_cosmic_sdk_examples.py +141 -0
- package/skills/cosmic-build/scripts/test/test_data_model_contract.py +30 -5
- package/skills/cosmic-build/scripts/test/test_delivery_stage_boundary.py +2 -10
- package/skills/cosmic-build/scripts/test/test_dym_sync_background.py +11 -0
- package/skills/cosmic-build/scripts/test/test_dynamic_form_metadata_only_contract.py +59 -1
- package/skills/cosmic-build/scripts/test/test_guide_skeleton_contract.py +87 -43
- package/skills/cosmic-build/scripts/test/test_inspect_platform_sdk.py +71 -0
- package/skills/cosmic-build/scripts/test/test_kd_api.py +67 -19
- package/skills/cosmic-build/scripts/test/test_kingscript_sdk_sync.py +221 -0
- package/skills/cosmic-build/scripts/test/test_kingscript_source_gate.py +10 -0
- package/skills/cosmic-build/scripts/test/test_list_configuration_closure.py +18 -0
- package/skills/cosmic-build/scripts/test/test_long_session_regressions.py +116 -0
- package/skills/cosmic-build/scripts/test/test_mcp_cli.py +524 -0
- package/skills/cosmic-build/scripts/test/test_modeling_input_recovery.py +141 -0
- package/skills/cosmic-build/scripts/test/test_open_world_cli_catalog.py +36 -2
- package/skills/cosmic-build/scripts/test/test_platform_api_contract.py +161 -1
- package/skills/cosmic-build/scripts/test/test_plugin_business_contract.py +91 -0
- package/skills/cosmic-build/scripts/test/test_plugin_corpus.py +195 -0
- package/skills/cosmic-build/scripts/test/test_plugin_handoff.py +346 -1
- package/skills/cosmic-build/scripts/test/test_plugin_target_sdk.py +70 -0
- package/skills/cosmic-build/scripts/test/test_preview_url.py +44 -1
- package/skills/cosmic-build/scripts/test/test_property_batch.py +22 -0
- package/skills/cosmic-build/scripts/test/test_property_input_discovery.py +13 -11
- package/skills/cosmic-build/scripts/test/test_query_plugin_handoff.py +160 -0
- package/skills/cosmic-build/scripts/test/test_register_plugins.py +31 -1
- package/skills/cosmic-build/scripts/test/test_render_output_cards.py +50 -4
- package/skills/cosmic-build/scripts/test/test_report_business_contract.py +27 -0
- package/skills/cosmic-build/scripts/test/test_report_doc_contract_sync.py +5 -4
- package/skills/cosmic-build/scripts/test/test_report_sdk_optimization.py +36 -0
- package/skills/cosmic-build/scripts/test/test_rule_batch_evidence.py +1 -1
- package/skills/cosmic-build/scripts/test/test_rule_domain_contract.py +20 -0
- package/skills/cosmic-build/scripts/test/test_rule_function_formula.py +16 -6
- package/skills/cosmic-build/scripts/test/test_skill_entry_contract.py +1 -0
- package/skills/cosmic-build/scripts/test/test_test_environment.py +45 -0
- package/skills/cosmic-build/scripts/test/test_verify_plugin_loading.py +79 -0
- package/skills/cosmic-build/scripts/test_environment.py +49 -0
- package/skills/cosmic-build/scripts/verify_plugin_loading.py +71 -0
- package/skills/cosmic-build/skills/cosmic-coding-impl/SKILL.md +86 -162
- package/skills/cosmic-build/skills/cosmic-coding-script/ATTRIBUTION.md +1 -1
- package/skills/cosmic-build/skills/cosmic-coding-script/SKILL.md +45 -14
- package/skills/cosmic-build/skills/cosmic-coding-script/references/kwc-controller-authoring.md +6 -0
- package/skills/cosmic-build/skills/cosmic-coding-script/references/sdk/README.md +29 -19
- package/skills/cosmic-build/skills/cosmic-coding-script/references/sdk/docs//350/204/232/346/234/254SDK.md +3 -4
- package/skills/cosmic-build/skills/cosmic-coding-script/references/sdk/indexes/package-index.md +1 -1
- package/skills/cosmic-build/skills/cosmic-coding-script/references/sdk/strategy.md +27 -18
- package/skills/cosmic-build/skills/cosmic-meta-api/SKILL.md +11 -17
- package/skills/cosmic-build/skills/cosmic-meta-api/apis/ai_meta.md +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/apis/app_menu.md +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/apis/meta_log.md +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/control-authoring.json +45 -4
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/form-control-traits.json +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/layout-ui.json +18 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/menu-publish.json +8 -2
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/property-batch.json +7 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/property-input-index.json +3 -3
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/report-write-contracts.json +1 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/rule-domain.json +37 -5
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/rule-event-contract.json +24 -3
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/run-build-meta.json +61 -12
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/schema/dropdown-menu.schema.json +69 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/schema/report-write.schema.json +2 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/schema/rule-set.schema.json +1 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/schema/rule-write.schema.json +14 -7
- package/skills/cosmic-build/skills/cosmic-meta-api/docs/api-summary.md +2 -2
- package/skills/cosmic-build/skills/cosmic-meta-api/modules/app-action/SKILL.md +6 -3
- package/skills/cosmic-build/skills/cosmic-meta-api/modules/develop/SKILL.md +1 -2
- package/skills/cosmic-build/skills/cosmic-meta-api/modules/export/SKILL.md +5 -6
- package/skills/cosmic-build/skills/cosmic-meta-api/modules/init/SKILL.md +13 -36
- package/skills/cosmic-build/skills/cosmic-meta-api/modules/pdm/SKILL.md +8 -9
- package/skills/cosmic-build/skills/cosmic-meta-api/modules/pdm/scripts/config.json.example +5 -15
- package/skills/cosmic-build/skills/cosmic-meta-api/modules/reset/SKILL.md +6 -6
- package/skills/cosmic-build/skills/cosmic-meta-api/modules/usage/SKILL.md +20 -148
- package/skills/cosmic-build/skills/cosmic-meta-api/modules/verify/SKILL.md +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/build_receipts.py +171 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_apps.py +25 -6
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_controls.py +55 -21
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_fields.py +10 -3
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_formactions.py +63 -6
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_forms.py +59 -2
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_listui.py +8 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_metaops.py +36 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_plugins.py +115 -90
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_properties.py +666 -4
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_rules.py +1415 -87
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/commands.py +6 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/config.py +28 -15
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/execution_errors.py +40 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/formatters.py +32 -5
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/property_policy_contract.py +6 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/report_ops.py +113 -17
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/reset.py +3 -3
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/rule_contract.py +107 -26
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/build_meta_order.py +50 -49
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/cosmic_api.py +856 -150
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/field_decorator.py +47 -14
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_build_receipt_resume.py +374 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_cli_failure_contract.py +24 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_creation_identity_boundary.py +4 -2
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_dropdown_menu_contract.py +382 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_existing_form_ui.py +0 -25
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_field_decorator.py +50 -6
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_functional_group_resolution.py +83 -16
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_identity_template_resolution.py +103 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_report_plugin_contract.py +28 -2
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_report_readback_derivation.py +22 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_report_typed_filters.py +65 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_rule_write_closure.py +1041 -15
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_run_batch_post_build_recovery.py +65 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_run_batch_verification_evidence.py +17 -0
- package/skills/cosmic-build/skills/cosmic-meta-knowledge/generation/api-param-checklist.md +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-knowledge/generation/rule-modeling-guide.md +7 -4
- package/skills/cosmic-build/skills/cosmic-meta-modeling/SKILL.md +61 -13
- package/skills/cosmic-build/skills/cosmic-meta-modeling/modules/app-menu/SKILL.md +8 -0
- package/skills/cosmic-build/skills/cosmic-meta-modeling/modules/formtemplate/SKILL.md +5 -0
- package/skills/cosmic-build/skills/cosmic-meta-modeling/modules/formtemplate/dynamic-form-artifact-schema.md +5 -0
- package/skills/cosmic-build/skills/cosmic-meta-modeling/modules/report/SKILL.md +21 -9
- package/skills/cosmic-build/skills/cosmic-meta-modeling/references/authoring-entity-graphs.md +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-modeling/references/authoring-storage-constraints.md +5 -3
- package/skills/cosmic-build/skills/cosmic-meta-modeling/references/authoring-ui-composition.md +6 -3
- package/skills/cosmic-build/skills/cosmic-meta-modeling/references/creation-recovery.md +13 -0
- package/skills/cosmic-build/skills/cosmic-meta-modeling/references/parse-core.md +3 -0
- package/skills/cosmic-build/skills/cosmic-meta-modeling/scripts/data_model_contract.py +6 -1
- package/skills/cosmic-build/skills/cosmic-meta-modeling/scripts/data_model_emit.py +135 -87
- package/skills/cosmic-build/skills/cosmic-meta-modeling/scripts/field_type_registry.py +11 -1
- package/skills/cosmic-build/skills/cosmic-meta-modeling/scripts/isv_resolver.py +1 -3
- package/skills/cosmic-build/skills/cosmic-meta-modeling/scripts/report_validator.py +29 -0
- package/skills/cosmic-build/skills/cosmic-meta-modifier/SKILL.md +4 -2
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/context/SKILL.md +2 -2
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/execute/SKILL.md +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/operation/SKILL.md +5 -4
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/operation/operation-write.md +6 -2
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/operation/validation.md +2 -0
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/property/SKILL.md +20 -5
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/property/complex-apis.md +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/property/policy-grammar.md +4 -1
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/report-op/SKILL.md +9 -0
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/rule/SKILL.md +61 -4
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/rule/raw-rule-authoring.md +3 -1
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/rule/rule-actions.md +2 -2
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/rule/rule-reference.md +6 -6
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/rule/state.md +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/unit/SKILL.md +6 -3
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/verify/usage-guide.md +4 -4
- package/skills/cosmic-build/skills/cosmic-meta-modifier/references/list-filter-modification.md +4 -1
- package/skills/cosmic-build/skills/cosmic-meta-ui/SKILL.md +9 -1
- package/skills/cosmic-build/skills/cosmic-meta-ui/modules/button/SKILL.md +3 -0
- package/skills/cosmic-build/skills/mcp-server/SKILL.md +210 -0
- package/skills/cosmic-build/skills/mcp-server/scripts/mcp_cli.py +431 -0
- package/skills/cosmic-build/skills/openapi-gen/SKILL.md +3 -3
- package/skills/cosmic-build/skills/openapi-gen/scripts/api/gen_runner.py +2 -2
- package/skills/cosmic-dev-best-practices/references/bill-dev-convention.md +19 -9
- package/skills/cosmic-dev-best-practices/references/cosmic-meta-api.md +14 -11
- package/skills/cosmic-dev-best-practices/references/design-examples/basedata-design-example.md +1 -1
- package/skills/cosmic-dev-best-practices/references/design-examples/bill-design-example.md +1 -1
- package/skills/cosmic-dev-best-practices/references/elements/AssistantField.md +1 -1
- package/skills/cosmic-dev-best-practices/references/elements/BasedataField.md +2 -2
- package/skills/cosmic-dev-best-practices/references/elements/BasedataPropField.md +3 -3
- package/skills/cosmic-dev-best-practices/references/elements/CreaterField.md +2 -2
- package/skills/cosmic-dev-best-practices/references/elements/CurrencyField.md +2 -2
- package/skills/cosmic-dev-best-practices/references/elements/CustomerField.md +2 -2
- package/skills/cosmic-dev-best-practices/references/elements/FlexField.md +1 -1
- package/skills/cosmic-dev-best-practices/references/elements/MaterielField.md +2 -2
- package/skills/cosmic-dev-best-practices/references/elements/OrgField.md +2 -2
- package/skills/cosmic-dev-best-practices/references/elements/SupplierField.md +2 -2
- package/skills/cosmic-dev-best-practices/references/elements/UnitField.md +1 -1
- package/skills/cosmic-dev-best-practices/references/elements/UserField.md +3 -3
- package/skills/cosmic-dev-best-practices/references/elements/common-field-property-conventions.md +16 -11
- package/skills/cosmic-dev-best-practices/references/layout-control-convention.md +5 -4
- package/skills/erp-analysis/references/delivery-contract.md +4 -2
- package/skills/erp-analysis/templates/AGENTS.template.md +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/.dsh/cosmic/.kd/config.json +0 -21
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Read class signatures or selected bytecode from explicitly supplied target SDK libraries."""
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import argparse
|
|
7
|
+
import hashlib
|
|
8
|
+
import json
|
|
9
|
+
import os
|
|
10
|
+
import re
|
|
11
|
+
import shutil
|
|
12
|
+
import subprocess
|
|
13
|
+
import zipfile
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
|
|
16
|
+
from appconfig_load import inspect_config
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class SdkError(ValueError):
|
|
20
|
+
def __init__(self, code: str, message: str):
|
|
21
|
+
super().__init__(message)
|
|
22
|
+
self.code = code
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def inspect_sdk(jars: list[str], selector: str, members: list[str] | None = None,
|
|
26
|
+
*, mode: str = "signatures", javap: str | None = None) -> dict:
|
|
27
|
+
if not re.fullmatch(r"[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*", selector):
|
|
28
|
+
raise SdkError("SDK_CLASS_INVALID", "Supply one exact class or simple class name")
|
|
29
|
+
if mode == "bytecode" and not members:
|
|
30
|
+
raise SdkError("SDK_MEMBER_REQUIRED", "Bytecode inspection requires at least one --member")
|
|
31
|
+
if mode not in ("locate", "signatures", "bytecode"):
|
|
32
|
+
raise SdkError("SDK_MODE_INVALID", "Use locate, signatures, or bytecode")
|
|
33
|
+
libraries = list(dict.fromkeys(str(Path(item).expanduser().resolve()) for item in jars))
|
|
34
|
+
if not libraries or len(libraries) > 2000:
|
|
35
|
+
raise SdkError("SDK_LIBRARY_SCOPE_INVALID", "Supply 1–2000 target SDK JARs or a bounded SDK directory")
|
|
36
|
+
candidates = []
|
|
37
|
+
for filename in libraries:
|
|
38
|
+
file = Path(filename)
|
|
39
|
+
if not file.is_file() or file.suffix.lower() != ".jar":
|
|
40
|
+
raise SdkError("SDK_JAR_UNAVAILABLE", f"Target JAR is unavailable: {file}")
|
|
41
|
+
with zipfile.ZipFile(file) as jar:
|
|
42
|
+
matches = [name for name in jar.namelist() if name.endswith(".class")
|
|
43
|
+
and not name.startswith("META-INF/")
|
|
44
|
+
and (name == selector.replace(".", "/") + ".class" if "." in selector
|
|
45
|
+
else name.rsplit("/", 1)[-1] == selector + ".class")]
|
|
46
|
+
if not matches:
|
|
47
|
+
continue
|
|
48
|
+
manifest = jar.read("META-INF/MANIFEST.MF").decode("utf-8", "replace") if "META-INF/MANIFEST.MF" in jar.namelist() else ""
|
|
49
|
+
version = next((line.split(":", 1)[1].strip() for line in manifest.splitlines()
|
|
50
|
+
if line.startswith("Implementation-Version:")), None)
|
|
51
|
+
digest = hashlib.sha256(file.read_bytes()).hexdigest()
|
|
52
|
+
candidates += [{"class": name[:-6].replace("/", "."), "jarPath": filename,
|
|
53
|
+
"jarSha256": digest, "version": version,
|
|
54
|
+
"classSha256": hashlib.sha256(jar.read(name)).hexdigest()}
|
|
55
|
+
for name in matches]
|
|
56
|
+
if not candidates:
|
|
57
|
+
return {"status": False, "errorCode": "SDK_CLASS_NOT_FOUND", "class": selector,
|
|
58
|
+
"searchedJarCount": len(libraries),
|
|
59
|
+
"message": "No matching class in the supplied libraries; this does not establish absence from another SDK version"}
|
|
60
|
+
if len(candidates) != 1:
|
|
61
|
+
return {"status": False, "errorCode": "SDK_CLASS_AMBIGUOUS", "class": selector,
|
|
62
|
+
"candidateCount": len(candidates), "candidates": candidates[:50],
|
|
63
|
+
"message": "Select the exact class and target JAR; no library was chosen automatically"}
|
|
64
|
+
evidence = {"status": True, "mode": mode, **candidates[0], "searchedJarCount": len(libraries)}
|
|
65
|
+
if mode == "locate":
|
|
66
|
+
return evidence
|
|
67
|
+
config = inspect_config(write_derived=False)
|
|
68
|
+
configured = Path(str(config.get("JAVA_HOME") or "")) / "bin" / ("javap.exe" if os.name == "nt" else "javap")
|
|
69
|
+
executable = javap or (str(configured) if configured.is_file() else shutil.which("javap"))
|
|
70
|
+
if not executable:
|
|
71
|
+
raise SdkError("SDK_JAVAP_UNAVAILABLE", "javap is unavailable; supply --javap from the target JDK")
|
|
72
|
+
result = subprocess.run([executable, "-p" if mode == "bytecode" else "-public",
|
|
73
|
+
"-c" if mode == "bytecode" else "-s", *([] if mode == "bytecode" else ["-constants"]), "-classpath",
|
|
74
|
+
os.pathsep.join(libraries), evidence["class"]],
|
|
75
|
+
capture_output=True, text=True, timeout=20, check=False)
|
|
76
|
+
if result.returncode != 0:
|
|
77
|
+
return {**evidence, "status": False, "errorCode": "SDK_JAVAP_FAILED",
|
|
78
|
+
"exitCode": result.returncode, "message": result.stderr.strip()[:1500]}
|
|
79
|
+
blocks = []
|
|
80
|
+
lines = result.stdout.splitlines()
|
|
81
|
+
for line in lines:
|
|
82
|
+
if re.match(r"^ \S.*;\s*$", line):
|
|
83
|
+
blocks.append({"declaration": line.strip(), "details": []})
|
|
84
|
+
elif blocks and line.strip() and line != "}":
|
|
85
|
+
blocks[-1]["details"].append(line.rstrip())
|
|
86
|
+
selected = [block for block in blocks if not members or any(
|
|
87
|
+
re.search(r"(?:^|[ .$])" + re.escape(member) + r"\s*(?:\(|=|;)", block["declaration"])
|
|
88
|
+
for member in members)]
|
|
89
|
+
missing = [member for member in members or [] if not any(
|
|
90
|
+
re.search(r"(?:^|[ .$])" + re.escape(member) + r"\s*(?:\(|=|;)", block["declaration"])
|
|
91
|
+
for block in selected)]
|
|
92
|
+
output = {**evidence, "javapPath": str(Path(executable).resolve()),
|
|
93
|
+
"declaration": next((line for line in lines if line.endswith("{")), ""),
|
|
94
|
+
"members": selected, "missingDeclaredMembers": missing,
|
|
95
|
+
"evidenceScope": "Target class declarations or selected bytecode only; inherited members and actual event execution require separate evidence"}
|
|
96
|
+
if len(json.dumps(output, ensure_ascii=False).encode("utf-8")) > 24 * 1024:
|
|
97
|
+
return {**evidence, "status": False, "errorCode": "SDK_OUTPUT_TOO_LARGE",
|
|
98
|
+
"message": "Select fewer --member names; no partial evidence was reported as complete"}
|
|
99
|
+
return output
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def inspect_reference(jars: list[str], selector: str, *, listing: bool = False, first_line: int = 1, limit: int = 80) -> dict:
|
|
103
|
+
if not selector or not 1 <= first_line or not 1 <= limit <= 500:
|
|
104
|
+
raise SdkError("SDK_REFERENCE_INVALID", "Supply a resource selector, positive first line and limit 1–500")
|
|
105
|
+
libraries = list(dict.fromkeys(str(Path(item).expanduser().resolve()) for item in jars))
|
|
106
|
+
if not libraries or len(libraries) > 2000:
|
|
107
|
+
raise SdkError("SDK_LIBRARY_SCOPE_INVALID", "Supply 1–2000 explicit target libraries")
|
|
108
|
+
candidates = []
|
|
109
|
+
for filename in libraries:
|
|
110
|
+
with zipfile.ZipFile(filename) as jar:
|
|
111
|
+
candidates += [{"jarPath": filename, "resource": name} for name in jar.namelist()
|
|
112
|
+
if name.lower().endswith((".java", ".html", ".md", ".txt"))
|
|
113
|
+
and (selector.lower() in name.lower() if listing else name == selector)]
|
|
114
|
+
if listing:
|
|
115
|
+
return {"status": True, "mode": "reference-index", "total": len(candidates), "items": candidates[:50],
|
|
116
|
+
"evidenceScope": "Source/documentation resource names only; not verified class or API contracts"}
|
|
117
|
+
if len(candidates) != 1:
|
|
118
|
+
return {"status": False, "errorCode": "SDK_REFERENCE_NOT_UNIQUE", "candidates": candidates[:50],
|
|
119
|
+
"message": "Select one exact resource and JAR"}
|
|
120
|
+
candidate = candidates[0]
|
|
121
|
+
with zipfile.ZipFile(candidate["jarPath"]) as jar:
|
|
122
|
+
data = jar.read(candidate["resource"])
|
|
123
|
+
lines = data.decode("utf-8-sig").splitlines()
|
|
124
|
+
result = {"status": True, "mode": "reference-text", **candidate,
|
|
125
|
+
"jarSha256": hashlib.sha256(Path(candidate["jarPath"]).read_bytes()).hexdigest(),
|
|
126
|
+
"resourceSha256": hashlib.sha256(data).hexdigest(), "firstLine": first_line,
|
|
127
|
+
"lineCount": len(lines), "nextLine": first_line + limit if first_line + limit <= len(lines) else None,
|
|
128
|
+
"content": "\n".join(lines[first_line - 1:first_line - 1 + limit]),
|
|
129
|
+
"evidenceScope": "Reference/source content; not execution instructions or proof of the running SDK version"}
|
|
130
|
+
if len(json.dumps(result, ensure_ascii=False).encode("utf-8")) > 24 * 1024:
|
|
131
|
+
raise SdkError("SDK_OUTPUT_TOO_LARGE", "Select fewer reference lines")
|
|
132
|
+
return result
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def main() -> int:
|
|
136
|
+
parser = argparse.ArgumentParser(description=__doc__)
|
|
137
|
+
selection = parser.add_mutually_exclusive_group(required=True)
|
|
138
|
+
selection.add_argument("--class", dest="selector")
|
|
139
|
+
selection.add_argument("--resource")
|
|
140
|
+
selection.add_argument("--list-resources")
|
|
141
|
+
parser.add_argument("--jar", action="append", default=[])
|
|
142
|
+
parser.add_argument("--sdk-dir", action="append", default=[])
|
|
143
|
+
parser.add_argument("--member", action="append")
|
|
144
|
+
parser.add_argument("--mode", choices=("locate", "signatures", "bytecode"), default="signatures")
|
|
145
|
+
parser.add_argument("--javap")
|
|
146
|
+
parser.add_argument("--first-line", type=int, default=1)
|
|
147
|
+
parser.add_argument("--limit", type=int, default=80)
|
|
148
|
+
args = parser.parse_args()
|
|
149
|
+
try:
|
|
150
|
+
if args.selector and (args.first_line != 1 or args.limit != 80):
|
|
151
|
+
raise SdkError("SDK_REFERENCE_ARGUMENT_INVALID", "--first-line and --limit apply to reference text only")
|
|
152
|
+
if not args.selector and (args.mode != "signatures" or args.member or args.javap):
|
|
153
|
+
raise SdkError("SDK_REFERENCE_ARGUMENT_INVALID", "Bytecode, member and javap options apply to classes only")
|
|
154
|
+
jars = list(args.jar)
|
|
155
|
+
for item in args.sdk_dir:
|
|
156
|
+
root = Path(item).expanduser().resolve()
|
|
157
|
+
if not root.is_dir():
|
|
158
|
+
raise SdkError("SDK_LIBRARY_SCOPE_INVALID", f"Target SDK directory is unavailable: {root}")
|
|
159
|
+
jars += [str(file) for file in root.rglob("*.jar")]
|
|
160
|
+
result = inspect_sdk(jars, args.selector, args.member, mode=args.mode, javap=args.javap) if args.selector else inspect_reference(
|
|
161
|
+
jars, args.resource or args.list_resources, listing=bool(args.list_resources), first_line=args.first_line, limit=args.limit)
|
|
162
|
+
except (SdkError, OSError, UnicodeError, zipfile.BadZipFile, subprocess.TimeoutExpired) as error:
|
|
163
|
+
result = {"status": False, "errorCode": getattr(error, "code", "SDK_INSPECTION_FAILED"), "message": str(error)}
|
|
164
|
+
print(json.dumps(result, ensure_ascii=False))
|
|
165
|
+
return 0 if result.get("status") is True else 2
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
if __name__ == "__main__":
|
|
169
|
+
raise SystemExit(main())
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
2
|
+
"""Unified business API entry point (facade).
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
-
|
|
6
|
-
- getToken / getAppToken / login
|
|
7
|
-
- accessToken
|
|
8
|
-
- x-acgw-identity
|
|
9
|
-
- token
|
|
4
|
+
Business scripts only call ``kd_api.post/get``, and are unaware of:
|
|
5
|
+
- enhanced vs. legacy authentication
|
|
6
|
+
- getToken / getAppToken / login URLs
|
|
7
|
+
- differences between accessToken and access_token
|
|
8
|
+
- how x-acgw-identity is injected
|
|
9
|
+
- token caching / refresh
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
Orchestration chain: kd_env_loader(config decrypted) -> kd_auth.get_token -> kd_auth.make_auth_headers
|
|
12
|
+
-> _http_client.http_post_json -> 401 (HTTP or business code) force-refresh and retry once.
|
|
13
13
|
"""
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
@@ -31,10 +31,10 @@ def _resolve_base(base_url: str | None, config: dict) -> str:
|
|
|
31
31
|
|
|
32
32
|
def _request_once(url: str, config: dict, token: str, *, method: str,
|
|
33
33
|
body: dict | None, params: dict | None, style: str) -> dict:
|
|
34
|
-
"""
|
|
34
|
+
"""Send a single request + body-level 401 normalization (HTTP 401 / business code 401 -> TokenExpiredError).
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
GET transport failures can retry. POST response loss leaves the write unknown
|
|
37
|
+
and must never replay automatically. Confirmed auth rejection still permits refresh.
|
|
38
38
|
"""
|
|
39
39
|
headers = kd_auth.make_auth_headers(config, token, style=style)
|
|
40
40
|
try:
|
|
@@ -48,13 +48,14 @@ def _request_once(url: str, config: dict, token: str, *, method: str,
|
|
|
48
48
|
)
|
|
49
49
|
else:
|
|
50
50
|
resp = _http_client.retry_call(
|
|
51
|
-
_http_client.http_post_json, url, body or {}, headers=headers, timeout=60
|
|
51
|
+
_http_client.http_post_json, url, body or {}, headers=headers, timeout=60,
|
|
52
|
+
retry_on_transient=False
|
|
52
53
|
)
|
|
53
54
|
except urllib.error.HTTPError as e:
|
|
54
55
|
if e.code == 401:
|
|
55
56
|
raise kd_auth.TokenExpiredError(f"HTTP 401 from {url}") from e
|
|
56
57
|
raise
|
|
57
|
-
#
|
|
58
|
+
# Body-level business code 401 normalization (platform often returns HTTP 200 + body errorCode=401)
|
|
58
59
|
kd_auth.raise_if_token_expired(resp)
|
|
59
60
|
return resp
|
|
60
61
|
|
|
@@ -78,14 +79,14 @@ def post(
|
|
|
78
79
|
*,
|
|
79
80
|
style: str = "kapi",
|
|
80
81
|
) -> dict:
|
|
81
|
-
"""POST JSON
|
|
82
|
+
"""POST JSON to the platform API.
|
|
82
83
|
|
|
83
84
|
Args:
|
|
84
|
-
base_url:
|
|
85
|
-
path: API
|
|
86
|
-
config: server
|
|
87
|
-
body:
|
|
88
|
-
style: header
|
|
85
|
+
base_url: Environment root URL (e.g. https://xxx/ierp); falls back to config['baseUrl'] when None.
|
|
86
|
+
path: API path, e.g. "/kapi/v2/devportal/ai-meta/queryForms".
|
|
87
|
+
config: server configuration (includes appId/appSecret/accountId/acgwIdentity etc.; must be decrypted).
|
|
88
|
+
body: Request body.
|
|
89
|
+
style: header style; "kapi"->accessToken, "legacy_api"->access_token+api:true.
|
|
89
90
|
"""
|
|
90
91
|
base = _resolve_base(base_url, config)
|
|
91
92
|
return _call_with_retry(base, path, config, method="POST", body=body, params=None, style=style)
|
|
@@ -99,13 +100,13 @@ def get(
|
|
|
99
100
|
*,
|
|
100
101
|
style: str = "kapi",
|
|
101
102
|
) -> dict:
|
|
102
|
-
"""GET JSON
|
|
103
|
+
"""GET JSON (query parameters)."""
|
|
103
104
|
base = _resolve_base(base_url, config)
|
|
104
105
|
return _call_with_retry(base, path, config, method="GET", body=None, params=params, style=style)
|
|
105
106
|
|
|
106
107
|
|
|
107
108
|
def invalidate_cache(config: dict | None = None) -> None:
|
|
108
|
-
"""
|
|
109
|
+
"""Force the next call to re-fetch the token (after auth info changes)."""
|
|
109
110
|
import kd_token_cache
|
|
110
111
|
|
|
111
112
|
kd_token_cache.invalidate(None)
|
|
@@ -89,7 +89,7 @@ def build_app_token_payload(config: dict) -> dict[str, Any]:
|
|
|
89
89
|
def build_login_payload(config: dict, app_token: str) -> dict[str, Any]:
|
|
90
90
|
"""普通型 step2 login.do payload(user/logintype/password/apptoken/tenantid/accountId)。
|
|
91
91
|
|
|
92
|
-
logintype='2' + password 为 DeepSeekHarness
|
|
92
|
+
本地补丁 #7:logintype='2' + password 为 DeepSeekHarness 环境登录必需(上游用 usertype='Mobile')。
|
|
93
93
|
"""
|
|
94
94
|
from kd_env_loader import get_locale
|
|
95
95
|
|
|
@@ -45,7 +45,7 @@ def get_ai_output_language() -> str:
|
|
|
45
45
|
|
|
46
46
|
|
|
47
47
|
def _kd_config_path() -> Path:
|
|
48
|
-
"""
|
|
48
|
+
"""本地补丁 #4:工作区 .dsh/cosmic/.kd/config.json 优先;缺失时从技能模板自动拷贝(幂等),
|
|
49
49
|
拷贝失败则回退 ~/.kd/config.json。
|
|
50
50
|
|
|
51
51
|
per-workspace 凭证:每个 DSH 工作区在 <cwd>/.dsh/cosmic/.kd/config.json 持有一份
|
|
@@ -193,9 +193,9 @@ def _build_section(
|
|
|
193
193
|
"""
|
|
194
194
|
section = {
|
|
195
195
|
"baseUrl": _pick_value(source, "url", "baseUrl", default=default_base_url).rstrip("/"),
|
|
196
|
-
"tenantId": _pick_value(source, "tenantId", "tenantid"),
|
|
196
|
+
"tenantId": _pick_value(source, "tenantId", "tenantid"), # 本地补丁 #5:去掉 default="ierp"
|
|
197
197
|
"user": _pick_secret(source, "user", "username"),
|
|
198
|
-
"password": _pick_secret(source, "password"),
|
|
198
|
+
"password": _pick_secret(source, "password"), # 本地补丁 #5
|
|
199
199
|
"loginUser": _pick_secret(source, "username", "user"),
|
|
200
200
|
"userType": _pick_value(source, "usertype", "userType", "user_type", default="Mobile"),
|
|
201
201
|
"appId": _pick_value(source, "client_id", "appId"),
|
|
@@ -212,6 +212,16 @@ def _build_section(
|
|
|
212
212
|
return section
|
|
213
213
|
|
|
214
214
|
|
|
215
|
+
def load_environment_identity() -> dict[str, str]:
|
|
216
|
+
"""Read handoff identity without decrypting or retaining credentials."""
|
|
217
|
+
from test_environment import environment_identity
|
|
218
|
+
_name, source = _select_default_env(load_kd_config().get("env"))
|
|
219
|
+
return environment_identity({
|
|
220
|
+
"baseUrl": _pick_value(source, "url", "baseUrl"),
|
|
221
|
+
"accountId": _pick_value(source, "accountId"),
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
|
|
215
225
|
@lru_cache(maxsize=1)
|
|
216
226
|
def load_default_kd_env() -> dict[str, Any]:
|
|
217
227
|
kd_config = load_kd_config()
|
|
@@ -238,7 +248,7 @@ def load_effective_skill_config(repo_root: Path | None = None) -> dict[str, Any]
|
|
|
238
248
|
"baseUrl": server_env["baseUrl"],
|
|
239
249
|
"tenantId": server_env["tenantId"],
|
|
240
250
|
"user": server_env["user"],
|
|
241
|
-
"password": server_env.get("password", ""),
|
|
251
|
+
"password": server_env.get("password", ""), # 本地补丁 #6:明文直写
|
|
242
252
|
"loginUser": server_env.get("loginUser", ""),
|
|
243
253
|
"userType": server_env.get("userType", "Mobile"),
|
|
244
254
|
"appId": server_env["appId"],
|
|
@@ -291,7 +301,7 @@ def update_default_kd_env(updates: dict[str, Any]) -> list[str]:
|
|
|
291
301
|
"account_id": "accountId",
|
|
292
302
|
"app_id": "client_id",
|
|
293
303
|
"login_user": "username",
|
|
294
|
-
"password": "password",
|
|
304
|
+
"password": "password", # 本地补丁 #6:明文直写
|
|
295
305
|
"normal_access_token": "normalAccessToken",
|
|
296
306
|
}
|
|
297
307
|
updated: list[str] = []
|
|
@@ -302,12 +312,11 @@ def update_default_kd_env(updates: dict[str, Any]) -> list[str]:
|
|
|
302
312
|
env_entry[new_key] = str(value).strip()
|
|
303
313
|
updated.append(old_key)
|
|
304
314
|
|
|
305
|
-
# 明文直写(本机工作区配置、不进 git;避免 Windows 沙箱下加密子进程需提权)
|
|
306
315
|
if updates.get("app_secret") is not None:
|
|
307
|
-
env_entry["client_secret"] = str(updates["app_secret"]).strip()
|
|
316
|
+
env_entry["client_secret"] = _encrypt_client_secret(str(updates["app_secret"]).strip())
|
|
308
317
|
updated.append("app_secret")
|
|
309
318
|
if updates.get("acgw_identity") is not None:
|
|
310
|
-
env_entry["x-acgw-identity"] = str(updates["acgw_identity"]).strip()
|
|
319
|
+
env_entry["x-acgw-identity"] = _encrypt_secret(str(updates["acgw_identity"]).strip(), "x-acgw-identity")
|
|
311
320
|
updated.append("acgw_identity")
|
|
312
321
|
|
|
313
322
|
with _kd_config_path().open("w", encoding="utf-8") as handle:
|
|
@@ -390,6 +399,7 @@ def update_pdm_kd_config(updates: dict[str, Any]) -> list[str]:
|
|
|
390
399
|
"account_id": "accountId",
|
|
391
400
|
"app_id": "client_id",
|
|
392
401
|
"login_user": "username",
|
|
402
|
+
"password": "password", # 本地补丁 #6:明文直写
|
|
393
403
|
"output": "outputDir",
|
|
394
404
|
}
|
|
395
405
|
updated: list[str] = []
|
|
@@ -400,9 +410,8 @@ def update_pdm_kd_config(updates: dict[str, Any]) -> list[str]:
|
|
|
400
410
|
pdm[new_key] = str(value).strip()
|
|
401
411
|
updated.append(old_key)
|
|
402
412
|
|
|
403
|
-
# 明文直写(本机工作区配置、不进 git;避免 Windows 沙箱下加密子进程需提权)
|
|
404
413
|
if updates.get("app_secret") is not None:
|
|
405
|
-
pdm["client_secret"] = str(updates["app_secret"]).strip()
|
|
414
|
+
pdm["client_secret"] = _encrypt_client_secret(str(updates["app_secret"]).strip())
|
|
406
415
|
updated.append("app_secret")
|
|
407
416
|
|
|
408
417
|
with _kd_config_path().open("w", encoding="utf-8") as handle:
|
|
@@ -57,7 +57,7 @@ def _resolve_project_root() -> str:
|
|
|
57
57
|
|
|
58
58
|
|
|
59
59
|
def _get_env_name() -> str:
|
|
60
|
-
"""
|
|
60
|
+
"""本地补丁 #8:从工作区配置 .dsh/cosmic/.kd/config.json 读取 default=true 的环境名,失败返回 'default'。"""
|
|
61
61
|
try:
|
|
62
62
|
config_path = Path(os.getcwd()) / ".dsh" / "cosmic" / ".kd" / "config.json"
|
|
63
63
|
with open(config_path, "r", encoding="utf-8-sig") as f:
|
|
@@ -225,7 +225,7 @@ def put(
|
|
|
225
225
|
response: dict | None = None,
|
|
226
226
|
ttl_min: int = DEFAULT_TTL_MIN,
|
|
227
227
|
) -> None:
|
|
228
|
-
"""写入 token
|
|
228
|
+
"""写入 token(本地补丁 #10:优先加密;加密不可用——如 Windows 沙箱禁子进程——时明文兜底,读取端两者皆可解)。"""
|
|
229
229
|
cache = _load_cache() or {"version": CACHE_VERSION, "tokens": {}}
|
|
230
230
|
cache["version"] = CACHE_VERSION
|
|
231
231
|
if response is not None:
|