sonnet-term 0.1.0__py3-none-any.whl
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.
- agent_core.py +1195 -0
- sonnet.py +1562 -0
- sonnet_data/__init__.py +67 -0
- sonnet_data/prompts_enc/bridge_prompt.bin +0 -0
- sonnet_data/prompts_enc/personalities.bin +0 -0
- sonnet_data/prompts_enc/system_prompt.bin +0 -0
- sonnet_data/skills/apple/apple-notes/SKILL.md +94 -0
- sonnet_data/skills/apple/apple-reminders/SKILL.md +130 -0
- sonnet_data/skills/apple/findmy/SKILL.md +131 -0
- sonnet_data/skills/apple/imessage/SKILL.md +102 -0
- sonnet_data/skills/autonomous-ai-agents/claude-code/SKILL.md +754 -0
- sonnet_data/skills/autonomous-ai-agents/codex/SKILL.md +151 -0
- sonnet_data/skills/autonomous-ai-agents/computer-use/SKILL.md +356 -0
- sonnet_data/skills/autonomous-ai-agents/hermes-agent/SKILL.md +213 -0
- sonnet_data/skills/autonomous-ai-agents/hermes-cli-automation/SKILL.md +100 -0
- sonnet_data/skills/autonomous-ai-agents/hermes-gateway-user-management/SKILL.md +207 -0
- sonnet_data/skills/autonomous-ai-agents/hermes-persona-engineering/SKILL.md +142 -0
- sonnet_data/skills/autonomous-ai-agents/opencode/SKILL.md +219 -0
- sonnet_data/skills/autonomous-ai-agents/subagent-fanout-batching/SKILL.md +55 -0
- sonnet_data/skills/autonomous-ai-agents/telegram-userbot-latency/SKILL.md +146 -0
- sonnet_data/skills/creative/architecture-diagram/SKILL.md +148 -0
- sonnet_data/skills/creative/ascii-art/SKILL.md +322 -0
- sonnet_data/skills/creative/ascii-video/SKILL.md +248 -0
- sonnet_data/skills/creative/baoyu-infographic/SKILL.md +237 -0
- sonnet_data/skills/creative/claude-design/SKILL.md +650 -0
- sonnet_data/skills/creative/comfyui/SKILL.md +612 -0
- sonnet_data/skills/creative/design-md/SKILL.md +220 -0
- sonnet_data/skills/creative/excalidraw/SKILL.md +199 -0
- sonnet_data/skills/creative/humanizer/SKILL.md +647 -0
- sonnet_data/skills/creative/manim-video/SKILL.md +275 -0
- sonnet_data/skills/creative/p5js/SKILL.md +558 -0
- sonnet_data/skills/creative/popular-web-designs/SKILL.md +214 -0
- sonnet_data/skills/creative/pretext/SKILL.md +220 -0
- sonnet_data/skills/creative/sketch/SKILL.md +220 -0
- sonnet_data/skills/creative/songwriting-and-ai-music/SKILL.md +308 -0
- sonnet_data/skills/creative/touchdesigner-mcp/SKILL.md +356 -0
- sonnet_data/skills/cybersecurity/abusing-dpapi-for-credential-access/SKILL.md +209 -0
- sonnet_data/skills/cybersecurity/abusing-shadow-credentials-for-privesc/SKILL.md +185 -0
- sonnet_data/skills/cybersecurity/achieving-cmmc-level-2-compliance/SKILL.md +142 -0
- sonnet_data/skills/cybersecurity/acquiring-disk-image-with-dd-and-dcfldd/SKILL.md +245 -0
- sonnet_data/skills/cybersecurity/analyzing-active-directory-acl-abuse/SKILL.md +90 -0
- sonnet_data/skills/cybersecurity/analyzing-android-malware-with-apktool/SKILL.md +66 -0
- sonnet_data/skills/cybersecurity/analyzing-api-gateway-access-logs/SKILL.md +81 -0
- sonnet_data/skills/cybersecurity/analyzing-apt-group-with-mitre-navigator/SKILL.md +290 -0
- sonnet_data/skills/cybersecurity/analyzing-azure-activity-logs-for-threats/SKILL.md +87 -0
- sonnet_data/skills/cybersecurity/analyzing-bootkit-and-rootkit-samples/SKILL.md +361 -0
- sonnet_data/skills/cybersecurity/analyzing-browser-forensics-with-hindsight/SKILL.md +299 -0
- sonnet_data/skills/cybersecurity/analyzing-campaign-attribution-evidence/SKILL.md +241 -0
- sonnet_data/skills/cybersecurity/analyzing-certificate-transparency-for-phishing/SKILL.md +370 -0
- sonnet_data/skills/cybersecurity/analyzing-cloud-storage-access-patterns/SKILL.md +77 -0
- sonnet_data/skills/cybersecurity/analyzing-cobalt-strike-beacon-configuration/SKILL.md +388 -0
- sonnet_data/skills/cybersecurity/analyzing-cobaltstrike-malleable-c2-profiles/SKILL.md +66 -0
- sonnet_data/skills/cybersecurity/analyzing-command-and-control-communication/SKILL.md +405 -0
- sonnet_data/skills/cybersecurity/analyzing-cyber-kill-chain/SKILL.md +148 -0
- sonnet_data/skills/cybersecurity/analyzing-disk-image-with-autopsy/SKILL.md +267 -0
- sonnet_data/skills/cybersecurity/analyzing-dns-logs-for-exfiltration/SKILL.md +309 -0
- sonnet_data/skills/cybersecurity/analyzing-docker-container-forensics/SKILL.md +345 -0
- sonnet_data/skills/cybersecurity/analyzing-email-headers-for-phishing-investigation/SKILL.md +365 -0
- sonnet_data/skills/cybersecurity/analyzing-ethereum-smart-contract-vulnerabilities/SKILL.md +71 -0
- sonnet_data/skills/cybersecurity/analyzing-golang-malware-with-ghidra/SKILL.md +320 -0
- sonnet_data/skills/cybersecurity/analyzing-heap-spray-exploitation/SKILL.md +64 -0
- sonnet_data/skills/cybersecurity/analyzing-indicators-of-compromise/SKILL.md +193 -0
- sonnet_data/skills/cybersecurity/analyzing-ios-app-security-with-objection/SKILL.md +206 -0
- sonnet_data/skills/cybersecurity/analyzing-kubernetes-audit-logs/SKILL.md +82 -0
- sonnet_data/skills/cybersecurity/analyzing-linux-audit-logs-for-intrusion/SKILL.md +275 -0
- sonnet_data/skills/cybersecurity/analyzing-linux-elf-malware/SKILL.md +370 -0
- sonnet_data/skills/cybersecurity/analyzing-linux-kernel-rootkits/SKILL.md +139 -0
- sonnet_data/skills/cybersecurity/analyzing-linux-system-artifacts/SKILL.md +339 -0
- sonnet_data/skills/cybersecurity/analyzing-lnk-file-and-jump-list-artifacts/SKILL.md +293 -0
- sonnet_data/skills/cybersecurity/analyzing-macro-malware-in-office-documents/SKILL.md +345 -0
- sonnet_data/skills/cybersecurity/analyzing-malicious-pdf-with-peepdf/SKILL.md +96 -0
- sonnet_data/skills/cybersecurity/analyzing-malicious-url-with-urlscan/SKILL.md +112 -0
- sonnet_data/skills/cybersecurity/analyzing-malware-behavior-with-cuckoo-sandbox/SKILL.md +304 -0
- sonnet_data/skills/cybersecurity/analyzing-malware-family-relationships-with-malpedia/SKILL.md +288 -0
- sonnet_data/skills/cybersecurity/analyzing-malware-persistence-with-autoruns/SKILL.md +129 -0
- sonnet_data/skills/cybersecurity/analyzing-malware-sandbox-evasion-techniques/SKILL.md +71 -0
- sonnet_data/skills/cybersecurity/analyzing-memory-dumps-with-volatility/SKILL.md +313 -0
- sonnet_data/skills/cybersecurity/analyzing-memory-forensics-with-lime-and-volatility/SKILL.md +91 -0
- sonnet_data/skills/cybersecurity/analyzing-mft-for-deleted-file-recovery/SKILL.md +261 -0
- sonnet_data/skills/cybersecurity/analyzing-network-covert-channels-in-malware/SKILL.md +220 -0
- sonnet_data/skills/cybersecurity/analyzing-network-flow-data-with-netflow/SKILL.md +72 -0
- sonnet_data/skills/cybersecurity/analyzing-network-packets-with-scapy/SKILL.md +61 -0
- sonnet_data/skills/cybersecurity/analyzing-network-traffic-for-incidents/SKILL.md +266 -0
- sonnet_data/skills/cybersecurity/analyzing-network-traffic-of-malware/SKILL.md +340 -0
- sonnet_data/skills/cybersecurity/analyzing-network-traffic-with-wireshark/SKILL.md +234 -0
- sonnet_data/skills/cybersecurity/analyzing-office365-audit-logs-for-compromise/SKILL.md +65 -0
- sonnet_data/skills/cybersecurity/analyzing-outlook-pst-for-email-forensics/SKILL.md +354 -0
- sonnet_data/skills/cybersecurity/analyzing-packed-malware-with-upx-unpacker/SKILL.md +311 -0
- sonnet_data/skills/cybersecurity/analyzing-pdf-malware-with-pdfid/SKILL.md +357 -0
- sonnet_data/skills/cybersecurity/analyzing-persistence-mechanisms-in-linux/SKILL.md +72 -0
- sonnet_data/skills/cybersecurity/analyzing-powershell-empire-artifacts/SKILL.md +72 -0
- sonnet_data/skills/cybersecurity/analyzing-powershell-script-block-logging/SKILL.md +77 -0
- sonnet_data/skills/cybersecurity/analyzing-prefetch-files-for-execution-history/SKILL.md +326 -0
- sonnet_data/skills/cybersecurity/analyzing-ransomware-encryption-mechanisms/SKILL.md +361 -0
- sonnet_data/skills/cybersecurity/analyzing-ransomware-leak-site-intelligence/SKILL.md +364 -0
- sonnet_data/skills/cybersecurity/analyzing-ransomware-network-indicators/SKILL.md +90 -0
- sonnet_data/skills/cybersecurity/analyzing-ransomware-payment-wallets/SKILL.md +199 -0
- sonnet_data/skills/cybersecurity/analyzing-sbom-for-supply-chain-vulnerabilities/SKILL.md +309 -0
- sonnet_data/skills/cybersecurity/analyzing-security-logs-with-splunk/SKILL.md +271 -0
- sonnet_data/skills/cybersecurity/analyzing-slack-space-and-file-system-artifacts/SKILL.md +399 -0
- sonnet_data/skills/cybersecurity/analyzing-supply-chain-malware-artifacts/SKILL.md +173 -0
- sonnet_data/skills/cybersecurity/analyzing-threat-actor-ttps-with-mitre-attack/SKILL.md +287 -0
- sonnet_data/skills/cybersecurity/analyzing-threat-actor-ttps-with-mitre-navigator/SKILL.md +87 -0
- sonnet_data/skills/cybersecurity/analyzing-threat-intelligence-feeds/SKILL.md +126 -0
- sonnet_data/skills/cybersecurity/analyzing-threat-landscape-with-misp/SKILL.md +82 -0
- sonnet_data/skills/cybersecurity/analyzing-tls-certificate-transparency-logs/SKILL.md +113 -0
- sonnet_data/skills/cybersecurity/analyzing-typosquatting-domains-with-dnstwist/SKILL.md +357 -0
- sonnet_data/skills/cybersecurity/analyzing-uefi-bootkit-persistence/SKILL.md +369 -0
- sonnet_data/skills/cybersecurity/analyzing-usb-device-connection-history/SKILL.md +371 -0
- sonnet_data/skills/cybersecurity/analyzing-web-server-logs-for-intrusion/SKILL.md +79 -0
- sonnet_data/skills/cybersecurity/analyzing-windows-amcache-artifacts/SKILL.md +253 -0
- sonnet_data/skills/cybersecurity/analyzing-windows-event-logs-in-splunk/SKILL.md +306 -0
- sonnet_data/skills/cybersecurity/analyzing-windows-lnk-files-for-artifacts/SKILL.md +329 -0
- sonnet_data/skills/cybersecurity/analyzing-windows-prefetch-with-python/SKILL.md +118 -0
- sonnet_data/skills/cybersecurity/analyzing-windows-registry-for-artifacts/SKILL.md +301 -0
- sonnet_data/skills/cybersecurity/analyzing-windows-shellbag-artifacts/SKILL.md +224 -0
- sonnet_data/skills/cybersecurity/assessing-vector-and-embedding-weaknesses/SKILL.md +236 -0
- sonnet_data/skills/cybersecurity/attacking-entra-id-with-roadtools/SKILL.md +206 -0
- sonnet_data/skills/cybersecurity/attacking-oauth-with-device-code-phishing/SKILL.md +245 -0
- sonnet_data/skills/cybersecurity/auditing-aws-s3-bucket-permissions/SKILL.md +274 -0
- sonnet_data/skills/cybersecurity/auditing-azure-active-directory-configuration/SKILL.md +275 -0
- sonnet_data/skills/cybersecurity/auditing-cloud-with-cis-benchmarks/SKILL.md +265 -0
- sonnet_data/skills/cybersecurity/auditing-entra-id-with-aadinternals/SKILL.md +188 -0
- sonnet_data/skills/cybersecurity/auditing-foundry-smart-contract-security/SKILL.md +170 -0
- sonnet_data/skills/cybersecurity/auditing-gcp-iam-permissions/SKILL.md +326 -0
- sonnet_data/skills/cybersecurity/auditing-kubernetes-cluster-rbac/SKILL.md +354 -0
- sonnet_data/skills/cybersecurity/auditing-kubernetes-rbac-privilege-escalation/SKILL.md +261 -0
- sonnet_data/skills/cybersecurity/auditing-mcp-servers-for-tool-poisoning/SKILL.md +218 -0
- sonnet_data/skills/cybersecurity/auditing-terraform-infrastructure-for-security/SKILL.md +358 -0
- sonnet_data/skills/cybersecurity/auditing-tls-certificate-transparency-logs/SKILL.md +203 -0
- sonnet_data/skills/cybersecurity/auditing-uefi-firmware-with-chipsec/SKILL.md +209 -0
- sonnet_data/skills/cybersecurity/automating-ioc-enrichment/SKILL.md +218 -0
- sonnet_data/skills/cybersecurity/benchmarking-kubernetes-with-kube-bench/SKILL.md +219 -0
- sonnet_data/skills/cybersecurity/building-adversary-infrastructure-tracking-system/SKILL.md +345 -0
- sonnet_data/skills/cybersecurity/building-attack-pattern-library-from-cti-reports/SKILL.md +327 -0
- sonnet_data/skills/cybersecurity/building-automated-malware-submission-pipeline/SKILL.md +507 -0
- sonnet_data/skills/cybersecurity/building-c2-infrastructure-with-sliver-framework/SKILL.md +212 -0
- sonnet_data/skills/cybersecurity/building-c2-redirector-infrastructure/SKILL.md +213 -0
- sonnet_data/skills/cybersecurity/building-cloud-siem-with-sentinel/SKILL.md +318 -0
- sonnet_data/skills/cybersecurity/building-detection-rule-with-splunk-spl/SKILL.md +261 -0
- sonnet_data/skills/cybersecurity/building-detection-rules-with-sigma/SKILL.md +338 -0
- sonnet_data/skills/cybersecurity/building-devsecops-pipeline-with-gitlab-ci/SKILL.md +263 -0
- sonnet_data/skills/cybersecurity/building-identity-federation-with-saml-azure-ad/SKILL.md +263 -0
- sonnet_data/skills/cybersecurity/building-identity-governance-lifecycle-process/SKILL.md +719 -0
- sonnet_data/skills/cybersecurity/building-incident-response-dashboard/SKILL.md +310 -0
- sonnet_data/skills/cybersecurity/building-incident-response-playbook/SKILL.md +267 -0
- sonnet_data/skills/cybersecurity/building-incident-timeline-with-timesketch/SKILL.md +272 -0
- sonnet_data/skills/cybersecurity/building-ioc-defanging-and-sharing-pipeline/SKILL.md +380 -0
- sonnet_data/skills/cybersecurity/building-ioc-enrichment-pipeline-with-opencti/SKILL.md +276 -0
- sonnet_data/skills/cybersecurity/building-malware-incident-communication-template/SKILL.md +347 -0
- sonnet_data/skills/cybersecurity/building-patch-tuesday-response-process/SKILL.md +227 -0
- sonnet_data/skills/cybersecurity/building-phishing-reporting-button-workflow/SKILL.md +128 -0
- sonnet_data/skills/cybersecurity/building-ransomware-playbook-with-cisa-framework/SKILL.md +207 -0
- sonnet_data/skills/cybersecurity/building-red-team-c2-infrastructure-with-havoc/SKILL.md +323 -0
- sonnet_data/skills/cybersecurity/building-role-mining-for-rbac-optimization/SKILL.md +262 -0
- sonnet_data/skills/cybersecurity/building-soc-escalation-matrix/SKILL.md +223 -0
- sonnet_data/skills/cybersecurity/building-soc-metrics-and-kpi-tracking/SKILL.md +313 -0
- sonnet_data/skills/cybersecurity/building-soc-playbook-for-ransomware/SKILL.md +309 -0
- sonnet_data/skills/cybersecurity/building-super-timelines-with-plaso/SKILL.md +169 -0
- sonnet_data/skills/cybersecurity/building-threat-actor-profile-from-osint/SKILL.md +380 -0
- sonnet_data/skills/cybersecurity/building-threat-feed-aggregation-with-misp/SKILL.md +343 -0
- sonnet_data/skills/cybersecurity/building-threat-hunt-hypothesis-framework/SKILL.md +95 -0
- sonnet_data/skills/cybersecurity/building-threat-intelligence-enrichment-in-splunk/SKILL.md +312 -0
- sonnet_data/skills/cybersecurity/building-threat-intelligence-feed-integration/SKILL.md +342 -0
- sonnet_data/skills/cybersecurity/building-threat-intelligence-platform/SKILL.md +321 -0
- sonnet_data/skills/cybersecurity/building-vulnerability-aging-and-sla-tracking/SKILL.md +291 -0
- sonnet_data/skills/cybersecurity/building-vulnerability-dashboard-with-defectdojo/SKILL.md +251 -0
- sonnet_data/skills/cybersecurity/building-vulnerability-exception-tracking-system/SKILL.md +183 -0
- sonnet_data/skills/cybersecurity/building-vulnerability-scanning-workflow/SKILL.md +352 -0
- sonnet_data/skills/cybersecurity/bypassing-authentication-with-forced-browsing/SKILL.md +284 -0
- sonnet_data/skills/cybersecurity/coercing-authentication-with-coercer-petitpotam/SKILL.md +175 -0
- sonnet_data/skills/cybersecurity/collecting-indicators-of-compromise/SKILL.md +272 -0
- sonnet_data/skills/cybersecurity/collecting-open-source-intelligence/SKILL.md +151 -0
- sonnet_data/skills/cybersecurity/collecting-threat-intelligence-with-misp/SKILL.md +191 -0
- sonnet_data/skills/cybersecurity/collecting-volatile-evidence-from-compromised-host/SKILL.md +251 -0
- sonnet_data/skills/cybersecurity/conducting-api-security-testing/SKILL.md +195 -0
- sonnet_data/skills/cybersecurity/conducting-cloud-incident-response/SKILL.md +289 -0
- sonnet_data/skills/cybersecurity/conducting-cloud-penetration-testing/SKILL.md +302 -0
- sonnet_data/skills/cybersecurity/conducting-cyber-risk-assessment-with-nist-800-30/SKILL.md +145 -0
- sonnet_data/skills/cybersecurity/conducting-domain-persistence-with-dcsync/SKILL.md +209 -0
- sonnet_data/skills/cybersecurity/conducting-external-reconnaissance-with-osint/SKILL.md +183 -0
- sonnet_data/skills/cybersecurity/conducting-full-scope-red-team-engagement/SKILL.md +202 -0
- sonnet_data/skills/cybersecurity/conducting-internal-network-penetration-test/SKILL.md +314 -0
- sonnet_data/skills/cybersecurity/conducting-internal-reconnaissance-with-bloodhound-ce/SKILL.md +198 -0
- sonnet_data/skills/cybersecurity/conducting-malware-incident-response/SKILL.md +222 -0
- sonnet_data/skills/cybersecurity/conducting-man-in-the-middle-attack-simulation/SKILL.md +295 -0
- sonnet_data/skills/cybersecurity/conducting-memory-forensics-with-volatility/SKILL.md +287 -0
- sonnet_data/skills/cybersecurity/conducting-mobile-app-penetration-test/SKILL.md +226 -0
- sonnet_data/skills/cybersecurity/conducting-network-penetration-test/SKILL.md +207 -0
- sonnet_data/skills/cybersecurity/conducting-pass-the-ticket-attack/SKILL.md +105 -0
- sonnet_data/skills/cybersecurity/conducting-phishing-incident-response/SKILL.md +282 -0
- sonnet_data/skills/cybersecurity/conducting-post-incident-lessons-learned/SKILL.md +191 -0
- sonnet_data/skills/cybersecurity/conducting-social-engineering-penetration-test/SKILL.md +370 -0
- sonnet_data/skills/cybersecurity/conducting-social-engineering-pretext-call/SKILL.md +221 -0
- sonnet_data/skills/cybersecurity/conducting-spearphishing-simulation-campaign/SKILL.md +173 -0
- sonnet_data/skills/cybersecurity/conducting-wireless-network-penetration-test/SKILL.md +188 -0
- sonnet_data/skills/cybersecurity/configuring-active-directory-tiered-model/SKILL.md +75 -0
- sonnet_data/skills/cybersecurity/configuring-aws-verified-access-for-ztna/SKILL.md +464 -0
- sonnet_data/skills/cybersecurity/configuring-certificate-authority-with-openssl/SKILL.md +103 -0
- sonnet_data/skills/cybersecurity/configuring-host-based-intrusion-detection/SKILL.md +230 -0
- sonnet_data/skills/cybersecurity/configuring-hsm-for-key-storage/SKILL.md +111 -0
- sonnet_data/skills/cybersecurity/configuring-identity-aware-proxy-with-google-iap/SKILL.md +413 -0
- sonnet_data/skills/cybersecurity/configuring-ldap-security-hardening/SKILL.md +95 -0
- sonnet_data/skills/cybersecurity/configuring-microsegmentation-for-zero-trust/SKILL.md +179 -0
- sonnet_data/skills/cybersecurity/configuring-multi-factor-authentication-with-duo/SKILL.md +157 -0
- sonnet_data/skills/cybersecurity/configuring-network-segmentation-with-vlans/SKILL.md +428 -0
- sonnet_data/skills/cybersecurity/configuring-oauth2-authorization-flow/SKILL.md +171 -0
- sonnet_data/skills/cybersecurity/configuring-pfsense-firewall-rules/SKILL.md +354 -0
- sonnet_data/skills/cybersecurity/configuring-snort-ids-for-intrusion-detection/SKILL.md +414 -0
- sonnet_data/skills/cybersecurity/configuring-suricata-for-network-monitoring/SKILL.md +409 -0
- sonnet_data/skills/cybersecurity/configuring-tls-1-3-for-secure-communications/SKILL.md +112 -0
- sonnet_data/skills/cybersecurity/configuring-windows-defender-advanced-settings/SKILL.md +292 -0
- sonnet_data/skills/cybersecurity/configuring-windows-event-logging-for-detection/SKILL.md +194 -0
- sonnet_data/skills/cybersecurity/configuring-zscaler-private-access-for-ztna/SKILL.md +318 -0
- sonnet_data/skills/cybersecurity/containing-active-breach/SKILL.md +231 -0
- sonnet_data/skills/cybersecurity/continuous-llm-red-teaming-with-promptfoo/SKILL.md +209 -0
- sonnet_data/skills/cybersecurity/correlating-security-events-in-qradar/SKILL.md +295 -0
- sonnet_data/skills/cybersecurity/correlating-threat-campaigns/SKILL.md +168 -0
- sonnet_data/skills/cybersecurity/defending-llms-with-guardrails/SKILL.md +284 -0
- sonnet_data/skills/cybersecurity/deobfuscating-javascript-malware/SKILL.md +360 -0
- sonnet_data/skills/cybersecurity/deobfuscating-powershell-obfuscated-malware/SKILL.md +386 -0
- sonnet_data/skills/cybersecurity/deploying-active-directory-honeytokens/SKILL.md +260 -0
- sonnet_data/skills/cybersecurity/deploying-cloud-deception-with-decoy-resources/SKILL.md +169 -0
- sonnet_data/skills/cybersecurity/deploying-cloudflare-access-for-zero-trust/SKILL.md +399 -0
- sonnet_data/skills/cybersecurity/deploying-decoy-files-for-ransomware-detection/SKILL.md +222 -0
- sonnet_data/skills/cybersecurity/deploying-edr-agent-with-crowdstrike/SKILL.md +275 -0
- sonnet_data/skills/cybersecurity/deploying-honeytokens-and-canarytokens/SKILL.md +232 -0
- sonnet_data/skills/cybersecurity/deploying-osquery-for-endpoint-monitoring/SKILL.md +205 -0
- sonnet_data/skills/cybersecurity/deploying-palo-alto-prisma-access-zero-trust/SKILL.md +305 -0
- sonnet_data/skills/cybersecurity/deploying-ransomware-canary-files/SKILL.md +113 -0
- sonnet_data/skills/cybersecurity/deploying-software-defined-perimeter/SKILL.md +191 -0
- sonnet_data/skills/cybersecurity/deploying-tailscale-for-zero-trust-vpn/SKILL.md +436 -0
- sonnet_data/skills/cybersecurity/designing-adversary-engagement-with-mitre-engage/SKILL.md +163 -0
- sonnet_data/skills/cybersecurity/detecting-ai-model-prompt-injection-attacks/SKILL.md +170 -0
- sonnet_data/skills/cybersecurity/detecting-anomalies-in-industrial-control-systems/SKILL.md +332 -0
- sonnet_data/skills/cybersecurity/detecting-anomalous-authentication-patterns/SKILL.md +757 -0
- sonnet_data/skills/cybersecurity/detecting-api-enumeration-attacks/SKILL.md +431 -0
- sonnet_data/skills/cybersecurity/detecting-arp-poisoning-in-network-traffic/SKILL.md +420 -0
- sonnet_data/skills/cybersecurity/detecting-attacks-on-historian-servers/SKILL.md +297 -0
- sonnet_data/skills/cybersecurity/detecting-attacks-on-scada-systems/SKILL.md +722 -0
- sonnet_data/skills/cybersecurity/detecting-aws-cloudtrail-anomalies/SKILL.md +94 -0
- sonnet_data/skills/cybersecurity/detecting-aws-credential-exposure-with-trufflehog/SKILL.md +311 -0
- sonnet_data/skills/cybersecurity/detecting-aws-guardduty-findings-automation/SKILL.md +348 -0
- sonnet_data/skills/cybersecurity/detecting-aws-iam-privilege-escalation/SKILL.md +66 -0
- sonnet_data/skills/cybersecurity/detecting-azure-lateral-movement/SKILL.md +85 -0
- sonnet_data/skills/cybersecurity/detecting-azure-service-principal-abuse/SKILL.md +251 -0
- sonnet_data/skills/cybersecurity/detecting-azure-storage-account-misconfigurations/SKILL.md +75 -0
- sonnet_data/skills/cybersecurity/detecting-beaconing-patterns-with-zeek/SKILL.md +89 -0
- sonnet_data/skills/cybersecurity/detecting-bluetooth-low-energy-attacks/SKILL.md +315 -0
- sonnet_data/skills/cybersecurity/detecting-broken-object-property-level-authorization/SKILL.md +412 -0
- sonnet_data/skills/cybersecurity/detecting-business-email-compromise/SKILL.md +150 -0
- sonnet_data/skills/cybersecurity/detecting-business-email-compromise-with-ai/SKILL.md +150 -0
- sonnet_data/skills/cybersecurity/detecting-cloud-threats-with-guardduty/SKILL.md +297 -0
- sonnet_data/skills/cybersecurity/detecting-command-and-control-over-dns/SKILL.md +1379 -0
- sonnet_data/skills/cybersecurity/detecting-compromised-cloud-credentials/SKILL.md +374 -0
- sonnet_data/skills/cybersecurity/detecting-container-drift-at-runtime/SKILL.md +243 -0
- sonnet_data/skills/cybersecurity/detecting-container-escape-attempts/SKILL.md +324 -0
- sonnet_data/skills/cybersecurity/detecting-container-escape-with-falco-rules/SKILL.md +341 -0
- sonnet_data/skills/cybersecurity/detecting-container-runtime-threats-with-falco/SKILL.md +285 -0
- sonnet_data/skills/cybersecurity/detecting-credential-dumping-techniques/SKILL.md +96 -0
- sonnet_data/skills/cybersecurity/detecting-cryptomining-in-cloud/SKILL.md +362 -0
- sonnet_data/skills/cybersecurity/detecting-data-and-model-poisoning/SKILL.md +215 -0
- sonnet_data/skills/cybersecurity/detecting-dcsync-attack-in-active-directory/SKILL.md +159 -0
- sonnet_data/skills/cybersecurity/detecting-deepfake-audio-in-vishing-attacks/SKILL.md +276 -0
- sonnet_data/skills/cybersecurity/detecting-dependency-confusion/SKILL.md +224 -0
- sonnet_data/skills/cybersecurity/detecting-dll-sideloading-attacks/SKILL.md +108 -0
- sonnet_data/skills/cybersecurity/detecting-dnp3-protocol-anomalies/SKILL.md +365 -0
- sonnet_data/skills/cybersecurity/detecting-dns-exfiltration-with-dns-query-analysis/SKILL.md +449 -0
- sonnet_data/skills/cybersecurity/detecting-email-account-compromise/SKILL.md +65 -0
- sonnet_data/skills/cybersecurity/detecting-email-forwarding-rules-attack/SKILL.md +105 -0
- sonnet_data/skills/cybersecurity/detecting-entra-offensive-tools-in-graph-logs/SKILL.md +194 -0
- sonnet_data/skills/cybersecurity/detecting-evasion-techniques-in-endpoint-logs/SKILL.md +269 -0
- sonnet_data/skills/cybersecurity/detecting-exfiltration-over-dns-with-zeek/SKILL.md +94 -0
- sonnet_data/skills/cybersecurity/detecting-fileless-attacks-on-endpoints/SKILL.md +182 -0
- sonnet_data/skills/cybersecurity/detecting-fileless-malware-techniques/SKILL.md +433 -0
- sonnet_data/skills/cybersecurity/detecting-golden-ticket-attacks-in-kerberos-logs/SKILL.md +109 -0
- sonnet_data/skills/cybersecurity/detecting-golden-ticket-forgery/SKILL.md +72 -0
- sonnet_data/skills/cybersecurity/detecting-indirect-prompt-injection/SKILL.md +236 -0
- sonnet_data/skills/cybersecurity/detecting-insider-data-exfiltration-via-dlp/SKILL.md +85 -0
- sonnet_data/skills/cybersecurity/detecting-insider-threat-behaviors/SKILL.md +104 -0
- sonnet_data/skills/cybersecurity/detecting-insider-threat-with-ueba/SKILL.md +72 -0
- sonnet_data/skills/cybersecurity/detecting-kerberoasting-attacks/SKILL.md +106 -0
- sonnet_data/skills/cybersecurity/detecting-lateral-movement-in-network/SKILL.md +452 -0
- sonnet_data/skills/cybersecurity/detecting-lateral-movement-with-splunk/SKILL.md +117 -0
- sonnet_data/skills/cybersecurity/detecting-lateral-movement-with-zeek/SKILL.md +214 -0
- sonnet_data/skills/cybersecurity/detecting-living-off-the-land-attacks/SKILL.md +524 -0
- sonnet_data/skills/cybersecurity/detecting-living-off-the-land-with-lolbas/SKILL.md +74 -0
- sonnet_data/skills/cybersecurity/detecting-malicious-npm-packages/SKILL.md +199 -0
- sonnet_data/skills/cybersecurity/detecting-malicious-scheduled-tasks-with-sysmon/SKILL.md +86 -0
- sonnet_data/skills/cybersecurity/detecting-mimikatz-execution-patterns/SKILL.md +103 -0
- sonnet_data/skills/cybersecurity/detecting-misconfigured-azure-storage/SKILL.md +277 -0
- sonnet_data/skills/cybersecurity/detecting-mobile-malware-behavior/SKILL.md +242 -0
- sonnet_data/skills/cybersecurity/detecting-modbus-command-injection-attacks/SKILL.md +513 -0
- sonnet_data/skills/cybersecurity/detecting-modbus-protocol-anomalies/SKILL.md +397 -0
- sonnet_data/skills/cybersecurity/detecting-model-extraction-attacks/SKILL.md +204 -0
- sonnet_data/skills/cybersecurity/detecting-network-anomalies-with-zeek/SKILL.md +406 -0
- sonnet_data/skills/cybersecurity/detecting-network-scanning-with-ids-signatures/SKILL.md +310 -0
- sonnet_data/skills/cybersecurity/detecting-ntlm-relay-with-event-correlation/SKILL.md +768 -0
- sonnet_data/skills/cybersecurity/detecting-oauth-token-theft/SKILL.md +307 -0
- sonnet_data/skills/cybersecurity/detecting-pass-the-hash-attacks/SKILL.md +101 -0
- sonnet_data/skills/cybersecurity/detecting-pass-the-ticket-attacks/SKILL.md +69 -0
- sonnet_data/skills/cybersecurity/detecting-port-scanning-with-fail2ban/SKILL.md +377 -0
- sonnet_data/skills/cybersecurity/detecting-privilege-escalation-attempts/SKILL.md +102 -0
- sonnet_data/skills/cybersecurity/detecting-privilege-escalation-in-kubernetes-pods/SKILL.md +266 -0
- sonnet_data/skills/cybersecurity/detecting-process-hollowing-technique/SKILL.md +119 -0
- sonnet_data/skills/cybersecurity/detecting-process-injection-techniques/SKILL.md +371 -0
- sonnet_data/skills/cybersecurity/detecting-qr-code-phishing-with-email-security/SKILL.md +158 -0
- sonnet_data/skills/cybersecurity/detecting-ransomware-encryption-behavior/SKILL.md +238 -0
- sonnet_data/skills/cybersecurity/detecting-ransomware-precursors-in-network/SKILL.md +327 -0
- sonnet_data/skills/cybersecurity/detecting-rdp-brute-force-attacks/SKILL.md +80 -0
- sonnet_data/skills/cybersecurity/detecting-rootkit-activity/SKILL.md +313 -0
- sonnet_data/skills/cybersecurity/detecting-s3-data-exfiltration-attempts/SKILL.md +344 -0
- sonnet_data/skills/cybersecurity/detecting-secure-boot-bypass/SKILL.md +193 -0
- sonnet_data/skills/cybersecurity/detecting-serverless-function-injection/SKILL.md +505 -0
- sonnet_data/skills/cybersecurity/detecting-service-account-abuse/SKILL.md +105 -0
- sonnet_data/skills/cybersecurity/detecting-shadow-api-endpoints/SKILL.md +384 -0
- sonnet_data/skills/cybersecurity/detecting-shadow-it-cloud-usage/SKILL.md +68 -0
- sonnet_data/skills/cybersecurity/detecting-spearphishing-with-email-gateway/SKILL.md +152 -0
- sonnet_data/skills/cybersecurity/detecting-sql-injection-via-waf-logs/SKILL.md +72 -0
- sonnet_data/skills/cybersecurity/detecting-stuxnet-style-attacks/SKILL.md +494 -0
- sonnet_data/skills/cybersecurity/detecting-supply-chain-attacks-in-ci-cd/SKILL.md +90 -0
- sonnet_data/skills/cybersecurity/detecting-suspicious-oauth-application-consent/SKILL.md +65 -0
- sonnet_data/skills/cybersecurity/detecting-suspicious-powershell-execution/SKILL.md +105 -0
- sonnet_data/skills/cybersecurity/detecting-t1003-credential-dumping-with-edr/SKILL.md +191 -0
- sonnet_data/skills/cybersecurity/detecting-t1055-process-injection-with-sysmon/SKILL.md +180 -0
- sonnet_data/skills/cybersecurity/detecting-t1548-abuse-elevation-control-mechanism/SKILL.md +144 -0
- sonnet_data/skills/cybersecurity/detecting-typosquatting-packages/SKILL.md +230 -0
- sonnet_data/skills/cybersecurity/detecting-typosquatting-packages-in-npm-pypi/SKILL.md +176 -0
- sonnet_data/skills/cybersecurity/detecting-wmi-persistence/SKILL.md +101 -0
- sonnet_data/skills/cybersecurity/emulating-cloud-attacks-with-stratus-red-team/SKILL.md +224 -0
- sonnet_data/skills/cybersecurity/enumerating-cloud-with-cloudfox/SKILL.md +210 -0
- sonnet_data/skills/cybersecurity/eradicating-malware-from-infected-systems/SKILL.md +236 -0
- sonnet_data/skills/cybersecurity/escaping-containers-to-host/SKILL.md +276 -0
- sonnet_data/skills/cybersecurity/evaluating-threat-intelligence-platforms/SKILL.md +169 -0
- sonnet_data/skills/cybersecurity/executing-active-directory-attack-simulation/SKILL.md +197 -0
- sonnet_data/skills/cybersecurity/executing-nist-rmf-authorization-to-operate/SKILL.md +142 -0
- sonnet_data/skills/cybersecurity/executing-phishing-simulation-campaign/SKILL.md +233 -0
- sonnet_data/skills/cybersecurity/executing-red-team-engagement-planning/SKILL.md +159 -0
- sonnet_data/skills/cybersecurity/executing-red-team-exercise/SKILL.md +200 -0
- sonnet_data/skills/cybersecurity/exploiting-active-directory-certificate-services-esc1/SKILL.md +185 -0
- sonnet_data/skills/cybersecurity/exploiting-active-directory-with-bloodhound/SKILL.md +133 -0
- sonnet_data/skills/cybersecurity/exploiting-adcs-with-certipy/SKILL.md +205 -0
- sonnet_data/skills/cybersecurity/exploiting-api-injection-vulnerabilities/SKILL.md +479 -0
- sonnet_data/skills/cybersecurity/exploiting-aws-with-pacu/SKILL.md +216 -0
- sonnet_data/skills/cybersecurity/exploiting-bgp-hijacking-vulnerabilities/SKILL.md +357 -0
- sonnet_data/skills/cybersecurity/exploiting-broken-function-level-authorization/SKILL.md +379 -0
- sonnet_data/skills/cybersecurity/exploiting-broken-link-hijacking/SKILL.md +239 -0
- sonnet_data/skills/cybersecurity/exploiting-constrained-delegation-abuse/SKILL.md +209 -0
- sonnet_data/skills/cybersecurity/exploiting-deeplink-vulnerabilities/SKILL.md +190 -0
- sonnet_data/skills/cybersecurity/exploiting-excessive-data-exposure-in-api/SKILL.md +390 -0
- sonnet_data/skills/cybersecurity/exploiting-http-request-smuggling/SKILL.md +347 -0
- sonnet_data/skills/cybersecurity/exploiting-idor-vulnerabilities/SKILL.md +313 -0
- sonnet_data/skills/cybersecurity/exploiting-insecure-data-storage-in-mobile/SKILL.md +228 -0
- sonnet_data/skills/cybersecurity/exploiting-insecure-deserialization/SKILL.md +332 -0
- sonnet_data/skills/cybersecurity/exploiting-ipv6-vulnerabilities/SKILL.md +311 -0
- sonnet_data/skills/cybersecurity/exploiting-jwt-algorithm-confusion-attack/SKILL.md +469 -0
- sonnet_data/skills/cybersecurity/exploiting-kerberoasting-with-impacket/SKILL.md +234 -0
- sonnet_data/skills/cybersecurity/exploiting-mass-assignment-in-rest-apis/SKILL.md +242 -0
- sonnet_data/skills/cybersecurity/exploiting-ms17-010-eternalblue-vulnerability/SKILL.md +111 -0
- sonnet_data/skills/cybersecurity/exploiting-nopac-cve-2021-42278-42287/SKILL.md +202 -0
- sonnet_data/skills/cybersecurity/exploiting-nosql-injection-vulnerabilities/SKILL.md +221 -0
- sonnet_data/skills/cybersecurity/exploiting-oauth-misconfiguration/SKILL.md +316 -0
- sonnet_data/skills/cybersecurity/exploiting-prototype-pollution-in-javascript/SKILL.md +241 -0
- sonnet_data/skills/cybersecurity/exploiting-race-condition-vulnerabilities/SKILL.md +248 -0
- sonnet_data/skills/cybersecurity/exploiting-server-side-request-forgery/SKILL.md +354 -0
- sonnet_data/skills/cybersecurity/exploiting-smb-vulnerabilities-with-metasploit/SKILL.md +257 -0
- sonnet_data/skills/cybersecurity/exploiting-sql-injection-vulnerabilities/SKILL.md +205 -0
- sonnet_data/skills/cybersecurity/exploiting-sql-injection-with-sqlmap/SKILL.md +257 -0
- sonnet_data/skills/cybersecurity/exploiting-template-injection-vulnerabilities/SKILL.md +323 -0
- sonnet_data/skills/cybersecurity/exploiting-type-juggling-vulnerabilities/SKILL.md +274 -0
- sonnet_data/skills/cybersecurity/exploiting-vulnerabilities-with-metasploit-framework/SKILL.md +218 -0
- sonnet_data/skills/cybersecurity/exploiting-websocket-vulnerabilities/SKILL.md +424 -0
- sonnet_data/skills/cybersecurity/exploiting-zerologon-vulnerability-cve-2020-1472/SKILL.md +228 -0
- sonnet_data/skills/cybersecurity/extracting-browser-history-artifacts/SKILL.md +354 -0
- sonnet_data/skills/cybersecurity/extracting-config-from-agent-tesla-rat/SKILL.md +207 -0
- sonnet_data/skills/cybersecurity/extracting-credentials-from-memory-dump/SKILL.md +371 -0
- sonnet_data/skills/cybersecurity/extracting-iocs-from-malware-samples/SKILL.md +396 -0
- sonnet_data/skills/cybersecurity/extracting-memory-artifacts-with-rekall/SKILL.md +94 -0
- sonnet_data/skills/cybersecurity/extracting-windows-event-logs-artifacts/SKILL.md +343 -0
- sonnet_data/skills/cybersecurity/fleet-hunting-with-velociraptor/SKILL.md +197 -0
- sonnet_data/skills/cybersecurity/generating-and-analyzing-sboms/SKILL.md +186 -0
- sonnet_data/skills/cybersecurity/generating-forensic-timelines-with-hayabusa/SKILL.md +169 -0
- sonnet_data/skills/cybersecurity/generating-threat-intelligence-reports/SKILL.md +155 -0
- sonnet_data/skills/cybersecurity/hardening-docker-containers-for-production/SKILL.md +242 -0
- sonnet_data/skills/cybersecurity/hardening-docker-daemon-configuration/SKILL.md +330 -0
- sonnet_data/skills/cybersecurity/hardening-linux-endpoint-with-cis-benchmark/SKILL.md +238 -0
- sonnet_data/skills/cybersecurity/hardening-windows-endpoint-with-cis-benchmark/SKILL.md +210 -0
- sonnet_data/skills/cybersecurity/hunting-advanced-persistent-threats/SKILL.md +146 -0
- sonnet_data/skills/cybersecurity/hunting-bootkits-in-efi-system-partition/SKILL.md +222 -0
- sonnet_data/skills/cybersecurity/hunting-credential-stuffing-attacks/SKILL.md +105 -0
- sonnet_data/skills/cybersecurity/hunting-evtx-with-chainsaw/SKILL.md +177 -0
- sonnet_data/skills/cybersecurity/hunting-for-anomalous-powershell-execution/SKILL.md +81 -0
- sonnet_data/skills/cybersecurity/hunting-for-beaconing-with-frequency-analysis/SKILL.md +177 -0
- sonnet_data/skills/cybersecurity/hunting-for-cobalt-strike-beacons/SKILL.md +71 -0
- sonnet_data/skills/cybersecurity/hunting-for-command-and-control-beaconing/SKILL.md +120 -0
- sonnet_data/skills/cybersecurity/hunting-for-data-exfiltration-indicators/SKILL.md +120 -0
- sonnet_data/skills/cybersecurity/hunting-for-data-staging-before-exfiltration/SKILL.md +72 -0
- sonnet_data/skills/cybersecurity/hunting-for-dcom-lateral-movement/SKILL.md +686 -0
- sonnet_data/skills/cybersecurity/hunting-for-dcsync-attacks/SKILL.md +98 -0
- sonnet_data/skills/cybersecurity/hunting-for-defense-evasion-via-timestomping/SKILL.md +359 -0
- sonnet_data/skills/cybersecurity/hunting-for-dns-based-persistence/SKILL.md +77 -0
- sonnet_data/skills/cybersecurity/hunting-for-dns-tunneling-with-zeek/SKILL.md +156 -0
- sonnet_data/skills/cybersecurity/hunting-for-domain-fronting-c2-traffic/SKILL.md +72 -0
- sonnet_data/skills/cybersecurity/hunting-for-lateral-movement-via-wmi/SKILL.md +70 -0
- sonnet_data/skills/cybersecurity/hunting-for-living-off-the-cloud-techniques/SKILL.md +107 -0
- sonnet_data/skills/cybersecurity/hunting-for-living-off-the-land-binaries/SKILL.md +124 -0
- sonnet_data/skills/cybersecurity/hunting-for-lolbins-execution-in-endpoint-logs/SKILL.md +184 -0
- sonnet_data/skills/cybersecurity/hunting-for-ntlm-relay-attacks/SKILL.md +73 -0
- sonnet_data/skills/cybersecurity/hunting-for-persistence-mechanisms-in-windows/SKILL.md +119 -0
- sonnet_data/skills/cybersecurity/hunting-for-persistence-via-wmi-subscriptions/SKILL.md +151 -0
- sonnet_data/skills/cybersecurity/hunting-for-process-injection-techniques/SKILL.md +76 -0
- sonnet_data/skills/cybersecurity/hunting-for-registry-persistence-mechanisms/SKILL.md +107 -0
- sonnet_data/skills/cybersecurity/hunting-for-registry-run-key-persistence/SKILL.md +73 -0
- sonnet_data/skills/cybersecurity/hunting-for-scheduled-task-persistence/SKILL.md +101 -0
- sonnet_data/skills/cybersecurity/hunting-for-shadow-copy-deletion/SKILL.md +102 -0
- sonnet_data/skills/cybersecurity/hunting-for-spearphishing-indicators/SKILL.md +130 -0
- sonnet_data/skills/cybersecurity/hunting-for-startup-folder-persistence/SKILL.md +69 -0
- sonnet_data/skills/cybersecurity/hunting-for-supply-chain-compromise/SKILL.md +101 -0
- sonnet_data/skills/cybersecurity/hunting-for-suspicious-scheduled-tasks/SKILL.md +107 -0
- sonnet_data/skills/cybersecurity/hunting-for-t1098-account-manipulation/SKILL.md +71 -0
- sonnet_data/skills/cybersecurity/hunting-for-unusual-network-connections/SKILL.md +101 -0
- sonnet_data/skills/cybersecurity/hunting-for-unusual-service-installations/SKILL.md +70 -0
- sonnet_data/skills/cybersecurity/hunting-for-webshell-activity/SKILL.md +102 -0
- sonnet_data/skills/cybersecurity/hunting-saas-sso-token-abuse/SKILL.md +222 -0
- sonnet_data/skills/cybersecurity/igaming-platform-recon/SKILL.md +141 -0
- sonnet_data/skills/cybersecurity/implementing-aes-encryption-for-data-at-rest/SKILL.md +111 -0
- sonnet_data/skills/cybersecurity/implementing-alert-fatigue-reduction/SKILL.md +337 -0
- sonnet_data/skills/cybersecurity/implementing-anti-phishing-training-program/SKILL.md +130 -0
- sonnet_data/skills/cybersecurity/implementing-anti-ransomware-group-policy/SKILL.md +244 -0
- sonnet_data/skills/cybersecurity/implementing-api-abuse-detection-with-rate-limiting/SKILL.md +399 -0
- sonnet_data/skills/cybersecurity/implementing-api-gateway-security-controls/SKILL.md +468 -0
- sonnet_data/skills/cybersecurity/implementing-api-key-security-controls/SKILL.md +414 -0
- sonnet_data/skills/cybersecurity/implementing-api-rate-limiting-and-throttling/SKILL.md +481 -0
- sonnet_data/skills/cybersecurity/implementing-api-schema-validation-security/SKILL.md +438 -0
- sonnet_data/skills/cybersecurity/implementing-api-security-posture-management/SKILL.md +418 -0
- sonnet_data/skills/cybersecurity/implementing-api-security-testing-with-42crunch/SKILL.md +364 -0
- sonnet_data/skills/cybersecurity/implementing-api-threat-protection-with-apigee/SKILL.md +337 -0
- sonnet_data/skills/cybersecurity/implementing-application-whitelisting-with-applocker/SKILL.md +260 -0
- sonnet_data/skills/cybersecurity/implementing-aqua-security-for-container-scanning/SKILL.md +265 -0
- sonnet_data/skills/cybersecurity/implementing-attack-path-analysis-with-xm-cyber/SKILL.md +265 -0
- sonnet_data/skills/cybersecurity/implementing-attack-surface-management/SKILL.md +229 -0
- sonnet_data/skills/cybersecurity/implementing-aws-config-rules-for-compliance/SKILL.md +350 -0
- sonnet_data/skills/cybersecurity/implementing-aws-iam-permission-boundaries/SKILL.md +271 -0
- sonnet_data/skills/cybersecurity/implementing-aws-macie-for-data-classification/SKILL.md +331 -0
- sonnet_data/skills/cybersecurity/implementing-aws-nitro-enclave-security/SKILL.md +461 -0
- sonnet_data/skills/cybersecurity/implementing-aws-security-hub/SKILL.md +234 -0
- sonnet_data/skills/cybersecurity/implementing-aws-security-hub-compliance/SKILL.md +318 -0
- sonnet_data/skills/cybersecurity/implementing-azure-ad-privileged-identity-management/SKILL.md +273 -0
- sonnet_data/skills/cybersecurity/implementing-azure-defender-for-cloud/SKILL.md +329 -0
- sonnet_data/skills/cybersecurity/implementing-beyondcorp-zero-trust-access-model/SKILL.md +340 -0
- sonnet_data/skills/cybersecurity/implementing-bgp-security-with-rpki/SKILL.md +339 -0
- sonnet_data/skills/cybersecurity/implementing-browser-isolation-for-zero-trust/SKILL.md +422 -0
- sonnet_data/skills/cybersecurity/implementing-canary-tokens-for-network-intrusion/SKILL.md +335 -0
- sonnet_data/skills/cybersecurity/implementing-cisa-zero-trust-maturity-model/SKILL.md +351 -0
- sonnet_data/skills/cybersecurity/implementing-cloud-dlp-for-data-protection/SKILL.md +466 -0
- sonnet_data/skills/cybersecurity/implementing-cloud-security-posture-management/SKILL.md +303 -0
- sonnet_data/skills/cybersecurity/implementing-cloud-trail-log-analysis/SKILL.md +352 -0
- sonnet_data/skills/cybersecurity/implementing-cloud-vulnerability-posture-management/SKILL.md +236 -0
- sonnet_data/skills/cybersecurity/implementing-cloud-waf-rules/SKILL.md +319 -0
- sonnet_data/skills/cybersecurity/implementing-cloud-workload-protection/SKILL.md +84 -0
- sonnet_data/skills/cybersecurity/implementing-code-signing-for-artifacts/SKILL.md +235 -0
- sonnet_data/skills/cybersecurity/implementing-conditional-access-policies-azure-ad/SKILL.md +74 -0
- sonnet_data/skills/cybersecurity/implementing-conduit-security-for-ot-remote-access/SKILL.md +378 -0
- sonnet_data/skills/cybersecurity/implementing-container-image-minimal-base-with-distroless/SKILL.md +219 -0
- sonnet_data/skills/cybersecurity/implementing-container-network-policies-with-calico/SKILL.md +68 -0
- sonnet_data/skills/cybersecurity/implementing-continuous-security-validation-with-bas/SKILL.md +268 -0
- sonnet_data/skills/cybersecurity/implementing-data-loss-prevention-with-microsoft-purview/SKILL.md +601 -0
- sonnet_data/skills/cybersecurity/implementing-ddos-mitigation-with-cloudflare/SKILL.md +452 -0
- sonnet_data/skills/cybersecurity/implementing-deception-based-detection-with-canarytoken/SKILL.md +67 -0
- sonnet_data/skills/cybersecurity/implementing-delinea-secret-server-for-pam/SKILL.md +450 -0
- sonnet_data/skills/cybersecurity/implementing-device-posture-assessment-in-zero-trust/SKILL.md +458 -0
- sonnet_data/skills/cybersecurity/implementing-devsecops-security-scanning/SKILL.md +392 -0
- sonnet_data/skills/cybersecurity/implementing-diamond-model-analysis/SKILL.md +185 -0
- sonnet_data/skills/cybersecurity/implementing-digital-signatures-with-ed25519/SKILL.md +91 -0
- sonnet_data/skills/cybersecurity/implementing-disk-encryption-with-bitlocker/SKILL.md +228 -0
- sonnet_data/skills/cybersecurity/implementing-dmarc-dkim-spf-email-security/SKILL.md +129 -0
- sonnet_data/skills/cybersecurity/implementing-dragos-platform-for-ot-monitoring/SKILL.md +370 -0
- sonnet_data/skills/cybersecurity/implementing-ebpf-security-monitoring/SKILL.md +390 -0
- sonnet_data/skills/cybersecurity/implementing-email-sandboxing-with-proofpoint/SKILL.md +113 -0
- sonnet_data/skills/cybersecurity/implementing-end-to-end-encryption-for-messaging/SKILL.md +86 -0
- sonnet_data/skills/cybersecurity/implementing-endpoint-detection-with-wazuh/SKILL.md +71 -0
- sonnet_data/skills/cybersecurity/implementing-endpoint-dlp-controls/SKILL.md +176 -0
- sonnet_data/skills/cybersecurity/implementing-envelope-encryption-with-aws-kms/SKILL.md +100 -0
- sonnet_data/skills/cybersecurity/implementing-epss-score-for-vulnerability-prioritization/SKILL.md +221 -0
- sonnet_data/skills/cybersecurity/implementing-file-integrity-monitoring-with-aide/SKILL.md +63 -0
- sonnet_data/skills/cybersecurity/implementing-fuzz-testing-in-cicd-with-aflplusplus/SKILL.md +298 -0
- sonnet_data/skills/cybersecurity/implementing-gcp-binary-authorization/SKILL.md +288 -0
- sonnet_data/skills/cybersecurity/implementing-gcp-organization-policy-constraints/SKILL.md +276 -0
- sonnet_data/skills/cybersecurity/implementing-gcp-vpc-firewall-rules/SKILL.md +314 -0
- sonnet_data/skills/cybersecurity/implementing-gdpr-data-protection-controls/SKILL.md +194 -0
- sonnet_data/skills/cybersecurity/implementing-gdpr-data-subject-access-request/SKILL.md +303 -0
- sonnet_data/skills/cybersecurity/implementing-github-advanced-security-for-code-scanning/SKILL.md +212 -0
- sonnet_data/skills/cybersecurity/implementing-google-workspace-admin-security/SKILL.md +516 -0
- sonnet_data/skills/cybersecurity/implementing-google-workspace-phishing-protection/SKILL.md +138 -0
- sonnet_data/skills/cybersecurity/implementing-google-workspace-sso-configuration/SKILL.md +214 -0
- sonnet_data/skills/cybersecurity/implementing-hardware-security-key-authentication/SKILL.md +230 -0
- sonnet_data/skills/cybersecurity/implementing-hashicorp-vault-dynamic-secrets/SKILL.md +630 -0
- sonnet_data/skills/cybersecurity/implementing-hipaa-security-rule-safeguards/SKILL.md +142 -0
- sonnet_data/skills/cybersecurity/implementing-honeypot-for-ransomware-detection/SKILL.md +404 -0
- sonnet_data/skills/cybersecurity/implementing-honeytokens-for-breach-detection/SKILL.md +83 -0
- sonnet_data/skills/cybersecurity/implementing-ics-firewall-with-tofino/SKILL.md +360 -0
- sonnet_data/skills/cybersecurity/implementing-identity-governance-with-sailpoint/SKILL.md +101 -0
- sonnet_data/skills/cybersecurity/implementing-identity-verification-for-zero-trust/SKILL.md +249 -0
- sonnet_data/skills/cybersecurity/implementing-iec-62443-security-zones/SKILL.md +535 -0
- sonnet_data/skills/cybersecurity/implementing-image-provenance-verification-with-cosign/SKILL.md +336 -0
- sonnet_data/skills/cybersecurity/implementing-immutable-backup-with-restic/SKILL.md +110 -0
- sonnet_data/skills/cybersecurity/implementing-infrastructure-as-code-security-scanning/SKILL.md +267 -0
- sonnet_data/skills/cybersecurity/implementing-iso-27001-information-security-management/SKILL.md +183 -0
- sonnet_data/skills/cybersecurity/implementing-just-in-time-access-provisioning/SKILL.md +135 -0
- sonnet_data/skills/cybersecurity/implementing-jwt-signing-and-verification/SKILL.md +95 -0
- sonnet_data/skills/cybersecurity/implementing-kubernetes-network-policy-with-calico/SKILL.md +337 -0
- sonnet_data/skills/cybersecurity/implementing-kubernetes-pod-security-standards/SKILL.md +272 -0
- sonnet_data/skills/cybersecurity/implementing-llm-guardrails-for-security/SKILL.md +231 -0
- sonnet_data/skills/cybersecurity/implementing-log-forwarding-with-fluentd/SKILL.md +72 -0
- sonnet_data/skills/cybersecurity/implementing-log-integrity-with-blockchain/SKILL.md +73 -0
- sonnet_data/skills/cybersecurity/implementing-memory-protection-with-dep-aslr/SKILL.md +109 -0
- sonnet_data/skills/cybersecurity/implementing-microsegmentation-with-guardicore/SKILL.md +352 -0
- sonnet_data/skills/cybersecurity/implementing-mimecast-targeted-attack-protection/SKILL.md +162 -0
- sonnet_data/skills/cybersecurity/implementing-mitre-attack-coverage-mapping/SKILL.md +295 -0
- sonnet_data/skills/cybersecurity/implementing-mobile-application-management/SKILL.md +183 -0
- sonnet_data/skills/cybersecurity/implementing-mtls-for-zero-trust-services/SKILL.md +84 -0
- sonnet_data/skills/cybersecurity/implementing-nerc-cip-compliance-controls/SKILL.md +434 -0
- sonnet_data/skills/cybersecurity/implementing-network-access-control/SKILL.md +444 -0
- sonnet_data/skills/cybersecurity/implementing-network-access-control-with-cisco-ise/SKILL.md +351 -0
- sonnet_data/skills/cybersecurity/implementing-network-deception-with-honeypots/SKILL.md +92 -0
- sonnet_data/skills/cybersecurity/implementing-network-intrusion-prevention-with-suricata/SKILL.md +378 -0
- sonnet_data/skills/cybersecurity/implementing-network-policies-for-kubernetes/SKILL.md +241 -0
- sonnet_data/skills/cybersecurity/implementing-network-segmentation-for-ot/SKILL.md +496 -0
- sonnet_data/skills/cybersecurity/implementing-network-segmentation-with-firewall-zones/SKILL.md +349 -0
- sonnet_data/skills/cybersecurity/implementing-network-traffic-analysis-with-arkime/SKILL.md +74 -0
- sonnet_data/skills/cybersecurity/implementing-network-traffic-baselining/SKILL.md +66 -0
- sonnet_data/skills/cybersecurity/implementing-next-generation-firewall-with-palo-alto/SKILL.md +284 -0
- sonnet_data/skills/cybersecurity/implementing-opa-gatekeeper-for-policy-enforcement/SKILL.md +395 -0
- sonnet_data/skills/cybersecurity/implementing-ot-incident-response-playbook/SKILL.md +394 -0
- sonnet_data/skills/cybersecurity/implementing-ot-network-traffic-analysis-with-nozomi/SKILL.md +281 -0
- sonnet_data/skills/cybersecurity/implementing-pam-for-database-access/SKILL.md +101 -0
- sonnet_data/skills/cybersecurity/implementing-passwordless-auth-with-microsoft-entra/SKILL.md +580 -0
- sonnet_data/skills/cybersecurity/implementing-passwordless-authentication-with-fido2/SKILL.md +83 -0
- sonnet_data/skills/cybersecurity/implementing-patch-management-for-ot-systems/SKILL.md +352 -0
- sonnet_data/skills/cybersecurity/implementing-patch-management-workflow/SKILL.md +321 -0
- sonnet_data/skills/cybersecurity/implementing-pci-dss-compliance-controls/SKILL.md +150 -0
- sonnet_data/skills/cybersecurity/implementing-pod-security-admission-controller/SKILL.md +328 -0
- sonnet_data/skills/cybersecurity/implementing-policy-as-code-with-open-policy-agent/SKILL.md +332 -0
- sonnet_data/skills/cybersecurity/implementing-privileged-access-management-with-cyberark/SKILL.md +180 -0
- sonnet_data/skills/cybersecurity/implementing-privileged-access-workstation/SKILL.md +67 -0
- sonnet_data/skills/cybersecurity/implementing-privileged-session-monitoring/SKILL.md +340 -0
- sonnet_data/skills/cybersecurity/implementing-proofpoint-email-security-gateway/SKILL.md +165 -0
- sonnet_data/skills/cybersecurity/implementing-purdue-model-network-segmentation/SKILL.md +451 -0
- sonnet_data/skills/cybersecurity/implementing-ransomware-backup-strategy/SKILL.md +319 -0
- sonnet_data/skills/cybersecurity/implementing-ransomware-kill-switch-detection/SKILL.md +248 -0
- sonnet_data/skills/cybersecurity/implementing-rapid7-insightvm-for-scanning/SKILL.md +367 -0
- sonnet_data/skills/cybersecurity/implementing-rbac-hardening-for-kubernetes/SKILL.md +269 -0
- sonnet_data/skills/cybersecurity/implementing-rsa-key-pair-management/SKILL.md +102 -0
- sonnet_data/skills/cybersecurity/implementing-runtime-application-self-protection/SKILL.md +78 -0
- sonnet_data/skills/cybersecurity/implementing-runtime-security-with-tetragon/SKILL.md +303 -0
- sonnet_data/skills/cybersecurity/implementing-saml-sso-with-okta/SKILL.md +174 -0
- sonnet_data/skills/cybersecurity/implementing-scim-provisioning-with-okta/SKILL.md +256 -0
- sonnet_data/skills/cybersecurity/implementing-secret-scanning-with-gitleaks/SKILL.md +345 -0
- sonnet_data/skills/cybersecurity/implementing-secrets-management-with-vault/SKILL.md +348 -0
- sonnet_data/skills/cybersecurity/implementing-secrets-scanning-in-ci-cd/SKILL.md +92 -0
- sonnet_data/skills/cybersecurity/implementing-security-chaos-engineering/SKILL.md +97 -0
- sonnet_data/skills/cybersecurity/implementing-security-information-sharing-with-stix2/SKILL.md +417 -0
- sonnet_data/skills/cybersecurity/implementing-security-monitoring-with-datadog/SKILL.md +424 -0
- sonnet_data/skills/cybersecurity/implementing-semgrep-for-custom-sast-rules/SKILL.md +331 -0
- sonnet_data/skills/cybersecurity/implementing-siem-correlation-rules-for-apt/SKILL.md +94 -0
- sonnet_data/skills/cybersecurity/implementing-siem-use-case-tuning/SKILL.md +68 -0
- sonnet_data/skills/cybersecurity/implementing-siem-use-cases-for-detection/SKILL.md +327 -0
- sonnet_data/skills/cybersecurity/implementing-sigstore-for-software-signing/SKILL.md +202 -0
- sonnet_data/skills/cybersecurity/implementing-soar-automation-with-phantom/SKILL.md +420 -0
- sonnet_data/skills/cybersecurity/implementing-soar-playbook-for-phishing/SKILL.md +126 -0
- sonnet_data/skills/cybersecurity/implementing-soar-playbook-with-palo-alto-xsoar/SKILL.md +346 -0
- sonnet_data/skills/cybersecurity/implementing-stix-taxii-feed-integration/SKILL.md +318 -0
- sonnet_data/skills/cybersecurity/implementing-supply-chain-security-with-in-toto/SKILL.md +309 -0
- sonnet_data/skills/cybersecurity/implementing-syslog-centralization-with-rsyslog/SKILL.md +85 -0
- sonnet_data/skills/cybersecurity/implementing-taxii-server-with-opentaxii/SKILL.md +378 -0
- sonnet_data/skills/cybersecurity/implementing-threat-intelligence-lifecycle-management/SKILL.md +394 -0
- sonnet_data/skills/cybersecurity/implementing-threat-modeling-with-mitre-attack/SKILL.md +397 -0
- sonnet_data/skills/cybersecurity/implementing-ticketing-system-for-incidents/SKILL.md +430 -0
- sonnet_data/skills/cybersecurity/implementing-usb-device-control-policy/SKILL.md +156 -0
- sonnet_data/skills/cybersecurity/implementing-velociraptor-for-ir-collection/SKILL.md +303 -0
- sonnet_data/skills/cybersecurity/implementing-vulnerability-management-with-greenbone/SKILL.md +70 -0
- sonnet_data/skills/cybersecurity/implementing-vulnerability-remediation-sla/SKILL.md +193 -0
- sonnet_data/skills/cybersecurity/implementing-vulnerability-sla-breach-alerting/SKILL.md +307 -0
- sonnet_data/skills/cybersecurity/implementing-web-application-logging-with-modsecurity/SKILL.md +76 -0
- sonnet_data/skills/cybersecurity/implementing-zero-knowledge-proof-for-authentication/SKILL.md +86 -0
- sonnet_data/skills/cybersecurity/implementing-zero-standing-privilege-with-cyberark/SKILL.md +248 -0
- sonnet_data/skills/cybersecurity/implementing-zero-trust-dns-with-nextdns/SKILL.md +365 -0
- sonnet_data/skills/cybersecurity/implementing-zero-trust-for-saas-applications/SKILL.md +322 -0
- sonnet_data/skills/cybersecurity/implementing-zero-trust-in-cloud/SKILL.md +319 -0
- sonnet_data/skills/cybersecurity/implementing-zero-trust-network-access/SKILL.md +360 -0
- sonnet_data/skills/cybersecurity/implementing-zero-trust-network-access-with-zscaler/SKILL.md +177 -0
- sonnet_data/skills/cybersecurity/implementing-zero-trust-with-beyondcorp/SKILL.md +68 -0
- sonnet_data/skills/cybersecurity/implementing-zero-trust-with-hashicorp-boundary/SKILL.md +529 -0
- sonnet_data/skills/cybersecurity/integrating-dast-with-owasp-zap-in-pipeline/SKILL.md +256 -0
- sonnet_data/skills/cybersecurity/integrating-sast-into-github-actions-pipeline/SKILL.md +328 -0
- sonnet_data/skills/cybersecurity/intercepting-mobile-traffic-with-burpsuite/SKILL.md +202 -0
- sonnet_data/skills/cybersecurity/investigating-insider-threat-indicators/SKILL.md +312 -0
- sonnet_data/skills/cybersecurity/investigating-phishing-email-incident/SKILL.md +336 -0
- sonnet_data/skills/cybersecurity/investigating-ransomware-attack-artifacts/SKILL.md +415 -0
- sonnet_data/skills/cybersecurity/managing-cloud-identity-with-okta/SKILL.md +309 -0
- sonnet_data/skills/cybersecurity/managing-intelligence-lifecycle/SKILL.md +132 -0
- sonnet_data/skills/cybersecurity/managing-third-party-vendor-risk/SKILL.md +142 -0
- sonnet_data/skills/cybersecurity/mapping-attack-paths-with-bloodhound-ce/SKILL.md +228 -0
- sonnet_data/skills/cybersecurity/mapping-mitre-attack-techniques/SKILL.md +165 -0
- sonnet_data/skills/cybersecurity/migrating-to-post-quantum-cryptography/SKILL.md +213 -0
- sonnet_data/skills/cybersecurity/mobile-app-binary-review/SKILL.md +53 -0
- sonnet_data/skills/cybersecurity/modeling-threats-with-opencti/SKILL.md +270 -0
- sonnet_data/skills/cybersecurity/monitoring-darkweb-sources/SKILL.md +179 -0
- sonnet_data/skills/cybersecurity/monitoring-scada-modbus-traffic-anomalies/SKILL.md +348 -0
- sonnet_data/skills/cybersecurity/moving-laterally-with-netexec/SKILL.md +199 -0
- sonnet_data/skills/cybersecurity/operating-havoc-c2/SKILL.md +278 -0
- sonnet_data/skills/cybersecurity/operating-sliver-c2/SKILL.md +304 -0
- sonnet_data/skills/cybersecurity/operationalizing-misp-threat-feeds/SKILL.md +220 -0
- sonnet_data/skills/cybersecurity/orchestrating-llm-attacks-with-pyrit/SKILL.md +225 -0
- sonnet_data/skills/cybersecurity/parsing-artifacts-with-eric-zimmerman-tools/SKILL.md +170 -0
- sonnet_data/skills/cybersecurity/performing-access-recertification-with-saviynt/SKILL.md +291 -0
- sonnet_data/skills/cybersecurity/performing-access-review-and-certification/SKILL.md +148 -0
- sonnet_data/skills/cybersecurity/performing-active-directory-bloodhound-analysis/SKILL.md +249 -0
- sonnet_data/skills/cybersecurity/performing-active-directory-compromise-investigation/SKILL.md +210 -0
- sonnet_data/skills/cybersecurity/performing-active-directory-forest-trust-attack/SKILL.md +70 -0
- sonnet_data/skills/cybersecurity/performing-active-directory-penetration-test/SKILL.md +290 -0
- sonnet_data/skills/cybersecurity/performing-active-directory-vulnerability-assessment/SKILL.md +249 -0
- sonnet_data/skills/cybersecurity/performing-adversary-in-the-middle-phishing-detection/SKILL.md +161 -0
- sonnet_data/skills/cybersecurity/performing-agentless-vulnerability-scanning/SKILL.md +423 -0
- sonnet_data/skills/cybersecurity/performing-ai-driven-osint-correlation/SKILL.md +403 -0
- sonnet_data/skills/cybersecurity/performing-alert-triage-with-elastic-siem/SKILL.md +257 -0
- sonnet_data/skills/cybersecurity/performing-android-app-static-analysis-with-mobsf/SKILL.md +177 -0
- sonnet_data/skills/cybersecurity/performing-api-fuzzing-with-restler/SKILL.md +380 -0
- sonnet_data/skills/cybersecurity/performing-api-inventory-and-discovery/SKILL.md +444 -0
- sonnet_data/skills/cybersecurity/performing-api-rate-limiting-bypass/SKILL.md +420 -0
- sonnet_data/skills/cybersecurity/performing-api-security-testing-with-postman/SKILL.md +400 -0
- sonnet_data/skills/cybersecurity/performing-arp-spoofing-attack-simulation/SKILL.md +282 -0
- sonnet_data/skills/cybersecurity/performing-asset-criticality-scoring-for-vulns/SKILL.md +172 -0
- sonnet_data/skills/cybersecurity/performing-authenticated-scan-with-openvas/SKILL.md +275 -0
- sonnet_data/skills/cybersecurity/performing-authenticated-vulnerability-scan/SKILL.md +242 -0
- sonnet_data/skills/cybersecurity/performing-automated-malware-analysis-with-cape/SKILL.md +182 -0
- sonnet_data/skills/cybersecurity/performing-aws-account-enumeration-with-scout-suite/SKILL.md +266 -0
- sonnet_data/skills/cybersecurity/performing-aws-privilege-escalation-assessment/SKILL.md +291 -0
- sonnet_data/skills/cybersecurity/performing-bandwidth-throttling-attack-simulation/SKILL.md +335 -0
- sonnet_data/skills/cybersecurity/performing-binary-exploitation-analysis/SKILL.md +459 -0
- sonnet_data/skills/cybersecurity/performing-blind-ssrf-exploitation/SKILL.md +256 -0
- sonnet_data/skills/cybersecurity/performing-bluetooth-security-assessment/SKILL.md +92 -0
- sonnet_data/skills/cybersecurity/performing-brand-monitoring-for-impersonation/SKILL.md +290 -0
- sonnet_data/skills/cybersecurity/performing-clickjacking-attack-test/SKILL.md +441 -0
- sonnet_data/skills/cybersecurity/performing-cloud-asset-inventory-with-cartography/SKILL.md +256 -0
- sonnet_data/skills/cybersecurity/performing-cloud-forensics-investigation/SKILL.md +349 -0
- sonnet_data/skills/cybersecurity/performing-cloud-forensics-with-aws-cloudtrail/SKILL.md +96 -0
- sonnet_data/skills/cybersecurity/performing-cloud-incident-containment-procedures/SKILL.md +313 -0
- sonnet_data/skills/cybersecurity/performing-cloud-log-forensics-with-athena/SKILL.md +505 -0
- sonnet_data/skills/cybersecurity/performing-cloud-native-forensics-with-falco/SKILL.md +87 -0
- sonnet_data/skills/cybersecurity/performing-cloud-native-threat-hunting-with-aws-detective/SKILL.md +175 -0
- sonnet_data/skills/cybersecurity/performing-cloud-penetration-testing-with-pacu/SKILL.md +307 -0
- sonnet_data/skills/cybersecurity/performing-cloud-storage-forensic-acquisition/SKILL.md +362 -0
- sonnet_data/skills/cybersecurity/performing-container-escape-detection/SKILL.md +82 -0
- sonnet_data/skills/cybersecurity/performing-container-image-hardening/SKILL.md +265 -0
- sonnet_data/skills/cybersecurity/performing-container-security-scanning-with-trivy/SKILL.md +77 -0
- sonnet_data/skills/cybersecurity/performing-content-security-policy-bypass/SKILL.md +251 -0
- sonnet_data/skills/cybersecurity/performing-credential-access-with-lazagne/SKILL.md +261 -0
- sonnet_data/skills/cybersecurity/performing-cryptographic-audit-of-application/SKILL.md +111 -0
- sonnet_data/skills/cybersecurity/performing-csrf-attack-simulation/SKILL.md +365 -0
- sonnet_data/skills/cybersecurity/performing-cve-prioritization-with-kev-catalog/SKILL.md +272 -0
- sonnet_data/skills/cybersecurity/performing-dark-web-monitoring-for-threats/SKILL.md +270 -0
- sonnet_data/skills/cybersecurity/performing-deception-technology-deployment/SKILL.md +305 -0
- sonnet_data/skills/cybersecurity/performing-directory-traversal-testing/SKILL.md +331 -0
- sonnet_data/skills/cybersecurity/performing-disk-forensics-investigation/SKILL.md +272 -0
- sonnet_data/skills/cybersecurity/performing-dmarc-policy-enforcement-rollout/SKILL.md +139 -0
- sonnet_data/skills/cybersecurity/performing-dns-enumeration-and-zone-transfer/SKILL.md +275 -0
- sonnet_data/skills/cybersecurity/performing-dns-tunneling-detection/SKILL.md +92 -0
- sonnet_data/skills/cybersecurity/performing-docker-bench-security-assessment/SKILL.md +153 -0
- sonnet_data/skills/cybersecurity/performing-dynamic-analysis-of-android-app/SKILL.md +253 -0
- sonnet_data/skills/cybersecurity/performing-dynamic-analysis-with-any-run/SKILL.md +283 -0
- sonnet_data/skills/cybersecurity/performing-endpoint-forensics-investigation/SKILL.md +250 -0
- sonnet_data/skills/cybersecurity/performing-endpoint-vulnerability-remediation/SKILL.md +242 -0
- sonnet_data/skills/cybersecurity/performing-entitlement-review-with-sailpoint-iiq/SKILL.md +491 -0
- sonnet_data/skills/cybersecurity/performing-external-network-penetration-test/SKILL.md +358 -0
- sonnet_data/skills/cybersecurity/performing-false-positive-reduction-in-siem/SKILL.md +239 -0
- sonnet_data/skills/cybersecurity/performing-file-carving-with-foremost/SKILL.md +335 -0
- sonnet_data/skills/cybersecurity/performing-firmware-extraction-with-binwalk/SKILL.md +294 -0
- sonnet_data/skills/cybersecurity/performing-firmware-malware-analysis/SKILL.md +317 -0
- sonnet_data/skills/cybersecurity/performing-fuzzing-with-aflplusplus/SKILL.md +87 -0
- sonnet_data/skills/cybersecurity/performing-gcp-penetration-testing-with-gcpbucketbrute/SKILL.md +77 -0
- sonnet_data/skills/cybersecurity/performing-gcp-security-assessment-with-forseti/SKILL.md +300 -0
- sonnet_data/skills/cybersecurity/performing-graphql-depth-limit-attack/SKILL.md +424 -0
- sonnet_data/skills/cybersecurity/performing-graphql-introspection-attack/SKILL.md +526 -0
- sonnet_data/skills/cybersecurity/performing-graphql-security-assessment/SKILL.md +341 -0
- sonnet_data/skills/cybersecurity/performing-hardware-security-module-integration/SKILL.md +75 -0
- sonnet_data/skills/cybersecurity/performing-hash-cracking-with-hashcat/SKILL.md +96 -0
- sonnet_data/skills/cybersecurity/performing-http-parameter-pollution-attack/SKILL.md +211 -0
- sonnet_data/skills/cybersecurity/performing-ics-asset-discovery-with-claroty/SKILL.md +524 -0
- sonnet_data/skills/cybersecurity/performing-indicator-lifecycle-management/SKILL.md +148 -0
- sonnet_data/skills/cybersecurity/performing-initial-access-with-evilginx3/SKILL.md +224 -0
- sonnet_data/skills/cybersecurity/performing-insider-threat-investigation/SKILL.md +260 -0
- sonnet_data/skills/cybersecurity/performing-ioc-enrichment-automation/SKILL.md +433 -0
- sonnet_data/skills/cybersecurity/performing-ios-app-security-assessment/SKILL.md +289 -0
- sonnet_data/skills/cybersecurity/performing-iot-security-assessment/SKILL.md +202 -0
- sonnet_data/skills/cybersecurity/performing-ip-reputation-analysis-with-shodan/SKILL.md +305 -0
- sonnet_data/skills/cybersecurity/performing-jwt-none-algorithm-attack/SKILL.md +348 -0
- sonnet_data/skills/cybersecurity/performing-kerberoasting-attack/SKILL.md +119 -0
- sonnet_data/skills/cybersecurity/performing-kubernetes-cis-benchmark-with-kube-bench/SKILL.md +239 -0
- sonnet_data/skills/cybersecurity/performing-kubernetes-etcd-security-assessment/SKILL.md +227 -0
- sonnet_data/skills/cybersecurity/performing-kubernetes-penetration-testing/SKILL.md +283 -0
- sonnet_data/skills/cybersecurity/performing-lateral-movement-detection/SKILL.md +320 -0
- sonnet_data/skills/cybersecurity/performing-lateral-movement-with-wmiexec/SKILL.md +213 -0
- sonnet_data/skills/cybersecurity/performing-linux-log-forensics-investigation/SKILL.md +302 -0
- sonnet_data/skills/cybersecurity/performing-log-analysis-for-forensic-investigation/SKILL.md +325 -0
- sonnet_data/skills/cybersecurity/performing-log-source-onboarding-in-siem/SKILL.md +301 -0
- sonnet_data/skills/cybersecurity/performing-malware-hash-enrichment-with-virustotal/SKILL.md +351 -0
- sonnet_data/skills/cybersecurity/performing-malware-ioc-extraction/SKILL.md +376 -0
- sonnet_data/skills/cybersecurity/performing-malware-persistence-investigation/SKILL.md +475 -0
- sonnet_data/skills/cybersecurity/performing-malware-triage-with-yara/SKILL.md +381 -0
- sonnet_data/skills/cybersecurity/performing-memory-forensics-with-volatility3/SKILL.md +305 -0
- sonnet_data/skills/cybersecurity/performing-memory-forensics-with-volatility3-plugins/SKILL.md +243 -0
- sonnet_data/skills/cybersecurity/performing-mobile-app-certificate-pinning-bypass/SKILL.md +243 -0
- sonnet_data/skills/cybersecurity/performing-mobile-device-forensics-with-cellebrite/SKILL.md +348 -0
- sonnet_data/skills/cybersecurity/performing-network-forensics-with-wireshark/SKILL.md +317 -0
- sonnet_data/skills/cybersecurity/performing-network-packet-capture-analysis/SKILL.md +264 -0
- sonnet_data/skills/cybersecurity/performing-network-traffic-analysis-with-tshark/SKILL.md +64 -0
- sonnet_data/skills/cybersecurity/performing-network-traffic-analysis-with-zeek/SKILL.md +422 -0
- sonnet_data/skills/cybersecurity/performing-nist-csf-maturity-assessment/SKILL.md +141 -0
- sonnet_data/skills/cybersecurity/performing-oauth-scope-minimization-review/SKILL.md +654 -0
- sonnet_data/skills/cybersecurity/performing-oil-gas-cybersecurity-assessment/SKILL.md +369 -0
- sonnet_data/skills/cybersecurity/performing-open-source-intelligence-gathering/SKILL.md +142 -0
- sonnet_data/skills/cybersecurity/performing-osint-with-spiderfoot/SKILL.md +62 -0
- sonnet_data/skills/cybersecurity/performing-ot-network-security-assessment/SKILL.md +601 -0
- sonnet_data/skills/cybersecurity/performing-ot-vulnerability-assessment-with-claroty/SKILL.md +315 -0
- sonnet_data/skills/cybersecurity/performing-ot-vulnerability-scanning-safely/SKILL.md +298 -0
- sonnet_data/skills/cybersecurity/performing-packet-injection-attack/SKILL.md +334 -0
- sonnet_data/skills/cybersecurity/performing-paste-site-monitoring-for-credentials/SKILL.md +379 -0
- sonnet_data/skills/cybersecurity/performing-phishing-simulation-with-gophish/SKILL.md +149 -0
- sonnet_data/skills/cybersecurity/performing-physical-intrusion-assessment/SKILL.md +222 -0
- sonnet_data/skills/cybersecurity/performing-plc-firmware-security-analysis/SKILL.md +505 -0
- sonnet_data/skills/cybersecurity/performing-post-quantum-cryptography-migration/SKILL.md +345 -0
- sonnet_data/skills/cybersecurity/performing-power-grid-cybersecurity-assessment/SKILL.md +309 -0
- sonnet_data/skills/cybersecurity/performing-privacy-impact-assessment/SKILL.md +288 -0
- sonnet_data/skills/cybersecurity/performing-privilege-escalation-assessment/SKILL.md +219 -0
- sonnet_data/skills/cybersecurity/performing-privilege-escalation-on-linux/SKILL.md +122 -0
- sonnet_data/skills/cybersecurity/performing-privileged-account-access-review/SKILL.md +180 -0
- sonnet_data/skills/cybersecurity/performing-privileged-account-discovery/SKILL.md +73 -0
- sonnet_data/skills/cybersecurity/performing-purple-team-atomic-testing/SKILL.md +1010 -0
- sonnet_data/skills/cybersecurity/performing-purple-team-exercise/SKILL.md +316 -0
- sonnet_data/skills/cybersecurity/performing-ransomware-response/SKILL.md +260 -0
- sonnet_data/skills/cybersecurity/performing-ransomware-tabletop-exercise/SKILL.md +264 -0
- sonnet_data/skills/cybersecurity/performing-red-team-phishing-with-gophish/SKILL.md +103 -0
- sonnet_data/skills/cybersecurity/performing-red-team-with-covenant/SKILL.md +70 -0
- sonnet_data/skills/cybersecurity/performing-s7comm-protocol-security-analysis/SKILL.md +439 -0
- sonnet_data/skills/cybersecurity/performing-sca-dependency-scanning-with-snyk/SKILL.md +266 -0
- sonnet_data/skills/cybersecurity/performing-scada-hmi-security-assessment/SKILL.md +321 -0
- sonnet_data/skills/cybersecurity/performing-second-order-sql-injection/SKILL.md +235 -0
- sonnet_data/skills/cybersecurity/performing-security-headers-audit/SKILL.md +325 -0
- sonnet_data/skills/cybersecurity/performing-serverless-function-security-review/SKILL.md +306 -0
- sonnet_data/skills/cybersecurity/performing-service-account-audit/SKILL.md +132 -0
- sonnet_data/skills/cybersecurity/performing-service-account-credential-rotation/SKILL.md +305 -0
- sonnet_data/skills/cybersecurity/performing-soap-web-service-security-testing/SKILL.md +461 -0
- sonnet_data/skills/cybersecurity/performing-soc-tabletop-exercise/SKILL.md +408 -0
- sonnet_data/skills/cybersecurity/performing-soc2-type2-audit-preparation/SKILL.md +308 -0
- sonnet_data/skills/cybersecurity/performing-sqlite-database-forensics/SKILL.md +373 -0
- sonnet_data/skills/cybersecurity/performing-ssl-certificate-lifecycle-management/SKILL.md +97 -0
- sonnet_data/skills/cybersecurity/performing-ssl-stripping-attack/SKILL.md +270 -0
- sonnet_data/skills/cybersecurity/performing-ssl-tls-inspection-configuration/SKILL.md +296 -0
- sonnet_data/skills/cybersecurity/performing-ssl-tls-security-assessment/SKILL.md +71 -0
- sonnet_data/skills/cybersecurity/performing-ssrf-vulnerability-exploitation/SKILL.md +72 -0
- sonnet_data/skills/cybersecurity/performing-static-malware-analysis-with-pe-studio/SKILL.md +313 -0
- sonnet_data/skills/cybersecurity/performing-steganography-detection/SKILL.md +355 -0
- sonnet_data/skills/cybersecurity/performing-subdomain-enumeration-with-subfinder/SKILL.md +199 -0
- sonnet_data/skills/cybersecurity/performing-supply-chain-attack-simulation/SKILL.md +69 -0
- sonnet_data/skills/cybersecurity/performing-thick-client-application-penetration-test/SKILL.md +271 -0
- sonnet_data/skills/cybersecurity/performing-threat-emulation-with-atomic-red-team/SKILL.md +98 -0
- sonnet_data/skills/cybersecurity/performing-threat-hunting-with-elastic-siem/SKILL.md +293 -0
- sonnet_data/skills/cybersecurity/performing-threat-hunting-with-yara-rules/SKILL.md +433 -0
- sonnet_data/skills/cybersecurity/performing-threat-intelligence-sharing-with-misp/SKILL.md +72 -0
- sonnet_data/skills/cybersecurity/performing-threat-landscape-assessment-for-sector/SKILL.md +305 -0
- sonnet_data/skills/cybersecurity/performing-threat-modeling-with-owasp-threat-dragon/SKILL.md +217 -0
- sonnet_data/skills/cybersecurity/performing-timeline-reconstruction-with-plaso/SKILL.md +335 -0
- sonnet_data/skills/cybersecurity/performing-user-behavior-analytics/SKILL.md +260 -0
- sonnet_data/skills/cybersecurity/performing-vlan-hopping-attack/SKILL.md +335 -0
- sonnet_data/skills/cybersecurity/performing-vulnerability-scanning-with-nessus/SKILL.md +177 -0
- sonnet_data/skills/cybersecurity/performing-web-application-firewall-bypass/SKILL.md +265 -0
- sonnet_data/skills/cybersecurity/performing-web-application-penetration-test/SKILL.md +208 -0
- sonnet_data/skills/cybersecurity/performing-web-application-scanning-with-nikto/SKILL.md +247 -0
- sonnet_data/skills/cybersecurity/performing-web-application-vulnerability-triage/SKILL.md +250 -0
- sonnet_data/skills/cybersecurity/performing-web-cache-deception-attack/SKILL.md +228 -0
- sonnet_data/skills/cybersecurity/performing-web-cache-poisoning-attack/SKILL.md +327 -0
- sonnet_data/skills/cybersecurity/performing-wifi-password-cracking-with-aircrack/SKILL.md +283 -0
- sonnet_data/skills/cybersecurity/performing-windows-artifact-analysis-with-eric-zimmerman-tools/SKILL.md +295 -0
- sonnet_data/skills/cybersecurity/performing-wireless-network-penetration-test/SKILL.md +265 -0
- sonnet_data/skills/cybersecurity/performing-wireless-security-assessment-with-kismet/SKILL.md +397 -0
- sonnet_data/skills/cybersecurity/performing-yara-rule-development-for-detection/SKILL.md +345 -0
- sonnet_data/skills/cybersecurity/post-exploiting-microsoft-graph-with-graphrunner/SKILL.md +211 -0
- sonnet_data/skills/cybersecurity/prioritizing-vulnerabilities-with-cvss-scoring/SKILL.md +193 -0
- sonnet_data/skills/cybersecurity/processing-stix-taxii-feeds/SKILL.md +168 -0
- sonnet_data/skills/cybersecurity/profiling-threat-actor-groups/SKILL.md +143 -0
- sonnet_data/skills/cybersecurity/recovering-deleted-files-with-photorec/SKILL.md +252 -0
- sonnet_data/skills/cybersecurity/recovering-from-ransomware-attack/SKILL.md +340 -0
- sonnet_data/skills/cybersecurity/red-teaming-llms-with-garak/SKILL.md +226 -0
- sonnet_data/skills/cybersecurity/relaying-ntlm-for-adcs-esc8/SKILL.md +198 -0
- sonnet_data/skills/cybersecurity/remediating-s3-bucket-misconfiguration/SKILL.md +320 -0
- sonnet_data/skills/cybersecurity/reverse-engineering-android-malware-with-jadx/SKILL.md +361 -0
- sonnet_data/skills/cybersecurity/reverse-engineering-dotnet-malware-with-dnspy/SKILL.md +354 -0
- sonnet_data/skills/cybersecurity/reverse-engineering-ios-app-with-frida/SKILL.md +259 -0
- sonnet_data/skills/cybersecurity/reverse-engineering-malware-with-ghidra/SKILL.md +297 -0
- sonnet_data/skills/cybersecurity/reverse-engineering-ransomware-encryption-routine/SKILL.md +313 -0
- sonnet_data/skills/cybersecurity/reverse-engineering-rust-malware/SKILL.md +188 -0
- sonnet_data/skills/cybersecurity/scanning-container-images-with-grype/SKILL.md +238 -0
- sonnet_data/skills/cybersecurity/scanning-containers-with-trivy-in-cicd/SKILL.md +331 -0
- sonnet_data/skills/cybersecurity/scanning-docker-images-with-trivy/SKILL.md +271 -0
- sonnet_data/skills/cybersecurity/scanning-iac-and-images-with-trivy/SKILL.md +264 -0
- sonnet_data/skills/cybersecurity/scanning-infrastructure-with-nessus/SKILL.md +180 -0
- sonnet_data/skills/cybersecurity/scanning-kubernetes-manifests-with-kubesec/SKILL.md +307 -0
- sonnet_data/skills/cybersecurity/scanning-network-with-nmap-advanced/SKILL.md +215 -0
- sonnet_data/skills/cybersecurity/securing-agentic-ai-tool-invocation/SKILL.md +269 -0
- sonnet_data/skills/cybersecurity/securing-api-gateway-with-aws-waf/SKILL.md +458 -0
- sonnet_data/skills/cybersecurity/securing-aws-iam-permissions/SKILL.md +349 -0
- sonnet_data/skills/cybersecurity/securing-aws-lambda-execution-roles/SKILL.md +381 -0
- sonnet_data/skills/cybersecurity/securing-azure-with-microsoft-defender/SKILL.md +276 -0
- sonnet_data/skills/cybersecurity/securing-container-registry-images/SKILL.md +311 -0
- sonnet_data/skills/cybersecurity/securing-container-registry-with-harbor/SKILL.md +248 -0
- sonnet_data/skills/cybersecurity/securing-github-actions-workflows/SKILL.md +263 -0
- sonnet_data/skills/cybersecurity/securing-helm-chart-deployments/SKILL.md +298 -0
- sonnet_data/skills/cybersecurity/securing-historian-server-in-ot-environment/SKILL.md +390 -0
- sonnet_data/skills/cybersecurity/securing-kubernetes-on-cloud/SKILL.md +387 -0
- sonnet_data/skills/cybersecurity/securing-remote-access-to-ot-environment/SKILL.md +391 -0
- sonnet_data/skills/cybersecurity/securing-serverless-functions/SKILL.md +329 -0
- sonnet_data/skills/cybersecurity/terminal-screenshot-evidence/SKILL.md +40 -0
- sonnet_data/skills/cybersecurity/testing-android-intents-for-vulnerabilities/SKILL.md +194 -0
- sonnet_data/skills/cybersecurity/testing-api-authentication-weaknesses/SKILL.md +456 -0
- sonnet_data/skills/cybersecurity/testing-api-for-broken-object-level-authorization/SKILL.md +392 -0
- sonnet_data/skills/cybersecurity/testing-api-for-mass-assignment-vulnerability/SKILL.md +359 -0
- sonnet_data/skills/cybersecurity/testing-api-security-with-owasp-top-10/SKILL.md +355 -0
- sonnet_data/skills/cybersecurity/testing-cors-misconfiguration/SKILL.md +349 -0
- sonnet_data/skills/cybersecurity/testing-for-broken-access-control/SKILL.md +369 -0
- sonnet_data/skills/cybersecurity/testing-for-business-logic-vulnerabilities/SKILL.md +363 -0
- sonnet_data/skills/cybersecurity/testing-for-email-header-injection/SKILL.md +234 -0
- sonnet_data/skills/cybersecurity/testing-for-host-header-injection/SKILL.md +236 -0
- sonnet_data/skills/cybersecurity/testing-for-json-web-token-vulnerabilities/SKILL.md +246 -0
- sonnet_data/skills/cybersecurity/testing-for-open-redirect-vulnerabilities/SKILL.md +213 -0
- sonnet_data/skills/cybersecurity/testing-for-sensitive-data-exposure/SKILL.md +377 -0
- sonnet_data/skills/cybersecurity/testing-for-system-prompt-leakage/SKILL.md +215 -0
- sonnet_data/skills/cybersecurity/testing-for-xml-injection-vulnerabilities/SKILL.md +227 -0
- sonnet_data/skills/cybersecurity/testing-for-xss-vulnerabilities/SKILL.md +201 -0
- sonnet_data/skills/cybersecurity/testing-for-xss-vulnerabilities-with-burpsuite/SKILL.md +323 -0
- sonnet_data/skills/cybersecurity/testing-for-xxe-injection-vulnerabilities/SKILL.md +358 -0
- sonnet_data/skills/cybersecurity/testing-jwt-token-security/SKILL.md +354 -0
- sonnet_data/skills/cybersecurity/testing-mobile-api-authentication/SKILL.md +203 -0
- sonnet_data/skills/cybersecurity/testing-oauth2-implementation-flaws/SKILL.md +405 -0
- sonnet_data/skills/cybersecurity/testing-prompt-injection-in-rag-pipelines/SKILL.md +274 -0
- sonnet_data/skills/cybersecurity/testing-ransomware-recovery-procedures/SKILL.md +204 -0
- sonnet_data/skills/cybersecurity/testing-websocket-api-security/SKILL.md +446 -0
- sonnet_data/skills/cybersecurity/tracking-threat-actor-infrastructure/SKILL.md +339 -0
- sonnet_data/skills/cybersecurity/triaging-security-alerts-in-splunk/SKILL.md +224 -0
- sonnet_data/skills/cybersecurity/triaging-security-incident/SKILL.md +228 -0
- sonnet_data/skills/cybersecurity/triaging-security-incident-with-ir-playbook/SKILL.md +233 -0
- sonnet_data/skills/cybersecurity/triaging-vulnerabilities-with-ssvc-framework/SKILL.md +217 -0
- sonnet_data/skills/cybersecurity/triaging-windows-with-kape/SKILL.md +192 -0
- sonnet_data/skills/cybersecurity/validating-backup-integrity-for-recovery/SKILL.md +212 -0
- sonnet_data/skills/cybersecurity/validating-tpm-measured-boot-attestation/SKILL.md +183 -0
- sonnet_data/skills/cybersecurity/verifying-build-provenance-with-slsa-sigstore/SKILL.md +196 -0
- sonnet_data/skills/devops/cloudflare-workers-deploy/SKILL.md +60 -0
- sonnet_data/skills/devops/sdlc-review/SKILL.md +181 -0
- sonnet_data/skills/email/email-inbox-triage/SKILL.md +97 -0
- sonnet_data/skills/free-inference-models/SKILL.md +174 -0
- sonnet_data/skills/github/github-auth/SKILL.md +247 -0
- sonnet_data/skills/github/github-code-review/SKILL.md +481 -0
- sonnet_data/skills/github/github-issues/SKILL.md +370 -0
- sonnet_data/skills/github/github-pr-workflow/SKILL.md +367 -0
- sonnet_data/skills/github/github-repo-management/SKILL.md +516 -0
- sonnet_data/skills/humanize/SKILL.md +412 -0
- sonnet_data/skills/media/auto-clip/SKILL.md +276 -0
- sonnet_data/skills/media/gif-search/SKILL.md +91 -0
- sonnet_data/skills/media/media-analysis/SKILL.md +93 -0
- sonnet_data/skills/media/qwen-image-reverse-api/SKILL.md +62 -0
- sonnet_data/skills/media/qwen-tts/SKILL.md +67 -0
- sonnet_data/skills/media/songsee/SKILL.md +83 -0
- sonnet_data/skills/media/video-download-by-criteria/SKILL.md +80 -0
- sonnet_data/skills/media/video-subtitle-burn/SKILL.md +79 -0
- sonnet_data/skills/media/youtube-content/SKILL.md +76 -0
- sonnet_data/skills/mlops/deepseek-reasoning-jailbreak/SKILL.md +99 -0
- sonnet_data/skills/mlops/evaluation/evaluating-llms-harness/SKILL.md +498 -0
- sonnet_data/skills/mlops/evaluation/weights-and-biases/SKILL.md +598 -0
- sonnet_data/skills/mlops/genspark/SKILL.md +44 -0
- sonnet_data/skills/mlops/huggingface-hub/SKILL.md +81 -0
- sonnet_data/skills/mlops/inference/llama-cpp/SKILL.md +249 -0
- sonnet_data/skills/mlops/inference/serving-llms-vllm/SKILL.md +373 -0
- sonnet_data/skills/mlops/llm-jailbreak-techniques/SKILL.md +376 -0
- sonnet_data/skills/mlops/llm-prefill-jailbreak/SKILL.md +44 -0
- sonnet_data/skills/mlops/llm-provider-openai-compat/SKILL.md +61 -0
- sonnet_data/skills/mlops/llm-refusal-depth-tiers/SKILL.md +208 -0
- sonnet_data/skills/mlops/nous-free-models/SKILL.md +110 -0
- sonnet_data/skills/note-taking/obsidian/SKILL.md +68 -0
- sonnet_data/skills/productivity/airtable/SKILL.md +229 -0
- sonnet_data/skills/productivity/box/SKILL.md +117 -0
- sonnet_data/skills/productivity/document-to-action-items/SKILL.md +81 -0
- sonnet_data/skills/productivity/docx/SKILL.md +127 -0
- sonnet_data/skills/productivity/elevenlabs-tts-cron/SKILL.md +112 -0
- sonnet_data/skills/productivity/google-workspace/SKILL.md +335 -0
- sonnet_data/skills/productivity/maps/SKILL.md +195 -0
- sonnet_data/skills/productivity/meeting-action-items/SKILL.md +87 -0
- sonnet_data/skills/productivity/nano-pdf/SKILL.md +53 -0
- sonnet_data/skills/productivity/notion/SKILL.md +449 -0
- sonnet_data/skills/productivity/ocr-and-documents/SKILL.md +173 -0
- sonnet_data/skills/productivity/pdf/SKILL.md +174 -0
- sonnet_data/skills/productivity/powerpoint/SKILL.md +256 -0
- sonnet_data/skills/productivity/product-price-monitor/SKILL.md +79 -0
- sonnet_data/skills/productivity/screenshot-ocr/SKILL.md +102 -0
- sonnet_data/skills/productivity/teams-meeting-pipeline/SKILL.md +122 -0
- sonnet_data/skills/productivity/weekly-review-planning/SKILL.md +81 -0
- sonnet_data/skills/productivity/xlsx/SKILL.md +105 -0
- sonnet_data/skills/research/arxiv/SKILL.md +282 -0
- sonnet_data/skills/research/bitcoin-onchain-forensics/SKILL.md +60 -0
- sonnet_data/skills/research/blogwatcher/SKILL.md +137 -0
- sonnet_data/skills/research/competitor-news-monitor/SKILL.md +88 -0
- sonnet_data/skills/research/delegated-osint-research/SKILL.md +36 -0
- sonnet_data/skills/research/grounded-citations/SKILL.md +257 -0
- sonnet_data/skills/research/llm-wiki/SKILL.md +507 -0
- sonnet_data/skills/research/polymarket/SKILL.md +77 -0
- sonnet_data/skills/research/remote-freelance-job-hunting/SKILL.md +52 -0
- sonnet_data/skills/research/remote-job-board-aggregation/SKILL.md +82 -0
- sonnet_data/skills/research/remote-job-board-research/SKILL.md +65 -0
- sonnet_data/skills/research/remote-job-board-scraping/SKILL.md +109 -0
- sonnet_data/skills/research/remote-jobs-research/SKILL.md +71 -0
- sonnet_data/skills/research/research-paper-writing/SKILL.md +2377 -0
- sonnet_data/skills/research/solana-token-research/SKILL.md +63 -0
- sonnet_data/skills/research/web-research/SKILL.md +106 -0
- sonnet_data/skills/screenshot-ocr-fallback/SKILL.md +66 -0
- sonnet_data/skills/skill-directory/SKILL.md +1002 -0
- sonnet_data/skills/smart-home/openhue/SKILL.md +112 -0
- sonnet_data/skills/social-media/fb-group-autoposter/SKILL.md +64 -0
- sonnet_data/skills/social-media/reddit-user-harvest/SKILL.md +60 -0
- sonnet_data/skills/social-media/telegram-userbot/SKILL.md +529 -0
- sonnet_data/skills/social-media/telegram-userbot-hermes/SKILL.md +235 -0
- sonnet_data/skills/social-media/userbot-bridge-reliability/SKILL.md +419 -0
- sonnet_data/skills/social-media/x-twitter-sop-engagement/SKILL.md +95 -0
- sonnet_data/skills/social-media/xurl/SKILL.md +436 -0
- sonnet_data/skills/software-development/browser-automation/SKILL.md +141 -0
- sonnet_data/skills/software-development/codebase-inspection/SKILL.md +116 -0
- sonnet_data/skills/software-development/debugging-api-auth/SKILL.md +40 -0
- sonnet_data/skills/software-development/dogfood/SKILL.md +164 -0
- sonnet_data/skills/software-development/github/SKILL.md +56 -0
- sonnet_data/skills/software-development/hermes-agent-skill-authoring/SKILL.md +214 -0
- sonnet_data/skills/software-development/hermes-cli-embedding/SKILL.md +68 -0
- sonnet_data/skills/software-development/hermes-embedded-agent/SKILL.md +92 -0
- sonnet_data/skills/software-development/hermes-embedded-engine/SKILL.md +100 -0
- sonnet_data/skills/software-development/hermes-embedded-spawn/SKILL.md +156 -0
- sonnet_data/skills/software-development/hermes-session-db-file-recovery/SKILL.md +51 -0
- sonnet_data/skills/software-development/hermes-session-troubleshooting/SKILL.md +83 -0
- sonnet_data/skills/software-development/hermes-userbot-debug/SKILL.md +989 -0
- sonnet_data/skills/software-development/inspecting-hermes-desktop-dom/SKILL.md +159 -0
- sonnet_data/skills/software-development/node-express-backend-hardening/SKILL.md +50 -0
- sonnet_data/skills/software-development/node-inspect-debugger/SKILL.md +319 -0
- sonnet_data/skills/software-development/openai-compatible-api/SKILL.md +62 -0
- sonnet_data/skills/software-development/persona-extraction/SKILL.md +379 -0
- sonnet_data/skills/software-development/plan/SKILL.md +338 -0
- sonnet_data/skills/software-development/ponytail/SKILL.md +35 -0
- sonnet_data/skills/software-development/pyinstaller-wine-crossbuild/SKILL.md +207 -0
- sonnet_data/skills/software-development/python-debugpy/SKILL.md +390 -0
- sonnet_data/skills/software-development/realtime-candlestick-chart/SKILL.md +236 -0
- sonnet_data/skills/software-development/requesting-code-review/SKILL.md +285 -0
- sonnet_data/skills/software-development/safe-mass-code-refactor/SKILL.md +32 -0
- sonnet_data/skills/software-development/selenium-bot-automation/SKILL.md +42 -0
- sonnet_data/skills/software-development/simplify-code/SKILL.md +270 -0
- sonnet_data/skills/software-development/spike/SKILL.md +197 -0
- sonnet_data/skills/software-development/systematic-debugging/SKILL.md +411 -0
- sonnet_data/skills/software-development/telegram-userbot-debug/SKILL.md +657 -0
- sonnet_data/skills/software-development/test-driven-development/SKILL.md +362 -0
- sonnet_data/skills/software-development/textual-chat-dashboard/SKILL.md +176 -0
- sonnet_data/skills/software-development/textual-tui-chat-dashboard/SKILL.md +235 -0
- sonnet_data/skills/software-development/userbot-llm-provider-config/SKILL.md +180 -0
- sonnet_data/skills/software-development/userbot-persona-fleet-edit/SKILL.md +709 -0
- sonnet_data/skills/software-development/userbot-skill-deploy/SKILL.md +285 -0
- sonnet_data/skills/software-development/webview2-app-debugging/SKILL.md +46 -0
- sonnet_data/skills/software-development/webview2-desktop-app/SKILL.md +236 -0
- sonnet_data/skills/software-development/webview2-desktop-app-debug/SKILL.md +68 -0
- sonnet_data/skills/software-development/windows-exe-cross-build/SKILL.md +734 -0
- sonnet_data/skills/soul/SKILL.md +129 -0
- sonnet_data/skills/web/blocked-page-recovery/SKILL.md +137 -0
- sonnet_data/skills/web/tavily-search/SKILL.md +34 -0
- sonnet_data/skills/web3/nft-mint-bot/SKILL.md +92 -0
- sonnet_data/skills/web3/opensea-drop-eligibility/SKILL.md +127 -0
- sonnet_data/skills/web3/opensea-nft-mint-bot/SKILL.md +118 -0
- sonnet_data/skills/writing/no-ai-slop/SKILL.md +97 -0
- sonnet_json.py +1333 -0
- sonnet_term-0.1.0.dist-info/METADATA +657 -0
- sonnet_term-0.1.0.dist-info/RECORD +1000 -0
- sonnet_term-0.1.0.dist-info/WHEEL +5 -0
- sonnet_term-0.1.0.dist-info/entry_points.txt +2 -0
- sonnet_term-0.1.0.dist-info/top_level.txt +6 -0
- stream_filter.py +325 -0
- tools/__init__.py +7 -0
- tools/ansi2png.py +282 -0
- tools/chatline.py +285 -0
- tools/check_pixels.py +34 -0
- tools/codehl.py +337 -0
- tools/demo_palette.py +36 -0
- tools/panel_shot.py +36 -0
- tools/picker.py +234 -0
- tools/pty_capture.py +72 -0
- tools/pty_drive.py +125 -0
- tools/sesspicker.py +185 -0
- tools/updater.py +149 -0
- tools/wizard.py +241 -0
- tools/xterm256.py +47 -0
agent_core.py
ADDED
|
@@ -0,0 +1,1195 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""agent_core.py — Sonnet engine: spawn hermes subprocess + inject KINJI prompts.
|
|
3
|
+
Windows-friendly: pake subprocess, gak butuh tmux (kayak userbot Linux)."""
|
|
4
|
+
import json
|
|
5
|
+
import os
|
|
6
|
+
import queue
|
|
7
|
+
import shlex
|
|
8
|
+
import subprocess
|
|
9
|
+
import threading
|
|
10
|
+
import time
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
BASE = Path(__file__).resolve().parent
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _assets():
|
|
17
|
+
"""Resolusi lokasi prompts_enc + skills (paket terpasang / checkout)."""
|
|
18
|
+
try:
|
|
19
|
+
import sonnet_data
|
|
20
|
+
return sonnet_data.find()
|
|
21
|
+
except Exception:
|
|
22
|
+
return BASE / "prompts_enc", BASE / ".hermes" / "skills"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
PROMPTS, SKILLS_SRC = _assets()
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _hermes_home(workdir: Path) -> Path:
|
|
29
|
+
"""HERMES_HOME untuk instance ini.
|
|
30
|
+
|
|
31
|
+
`SONNET_HERMES_HOME` (dipakai CLI + pip install) menang. Kalau ga
|
|
32
|
+
di-set, baru fallback ke `<workdir>/.hermes` — itu benar untuk
|
|
33
|
+
checkout git, tapi salah untuk pip install karena workdir =
|
|
34
|
+
site-packages (read-only, dan state harus di user dir)."""
|
|
35
|
+
env = os.environ.get("SONNET_HERMES_HOME")
|
|
36
|
+
if env:
|
|
37
|
+
return Path(env).expanduser()
|
|
38
|
+
return workdir / ".hermes"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def find_hermes_binary() -> str:
|
|
42
|
+
"""FIX (31 Agu, direfactor 03 Sep jadi module-level biar bisa dipake
|
|
43
|
+
dari gui_server.py juga — mis. buat endpoint OAuth start): JANGAN
|
|
44
|
+
pake hermes system dari PATH user — itu versi berbeda & config-nya
|
|
45
|
+
gak nyambung ke workdir Sonnet (gejala: "no API keys or providers
|
|
46
|
+
found → run setup?"). Pilih hermes BUNDLED di runtime/ dulu, baru PATH."""
|
|
47
|
+
candidates = []
|
|
48
|
+
# runtime/ di samping backend/ (dist layout: runtime/python.exe,
|
|
49
|
+
# runtime/Scripts/hermes.exe kalo embeddable + pip install)
|
|
50
|
+
for base in (Path(__file__).resolve().parent.parent / "runtime",
|
|
51
|
+
BASE.parent / "runtime"):
|
|
52
|
+
if base.exists():
|
|
53
|
+
for name in ("hermes.exe", "hermes"):
|
|
54
|
+
p = base / name
|
|
55
|
+
if p.exists():
|
|
56
|
+
candidates.append(str(p))
|
|
57
|
+
# embeddable python: runtime/python.exe -m hermes_agent? gak
|
|
58
|
+
# — hermes punya entrypoint hermes.exe setelah pip install
|
|
59
|
+
import shutil
|
|
60
|
+
for name in ("hermes", "hermes.exe"):
|
|
61
|
+
hit = shutil.which(name)
|
|
62
|
+
if hit:
|
|
63
|
+
candidates.append(hit)
|
|
64
|
+
# preferensi: bundled dulu, path terakhir. Fallback "hermes" (bare,
|
|
65
|
+
# biar Popen coba lookup PATH sendiri) — SAMA kayak behavior lama,
|
|
66
|
+
# jangan diubah ke "" biar caller lama (spawn agent chat) gak berubah.
|
|
67
|
+
return candidates[0] if candidates else "hermes"
|
|
68
|
+
|
|
69
|
+
# FIX (02 Sep #13): provider slug → hermes-CLI key env var mapping.
|
|
70
|
+
# Kalo provider lo gak ada di sini, fallback ke `<PROVIDER>_API_KEY`
|
|
71
|
+
# (auto-derive dari slug). Tambah di sini kalo hermes butuh nama env
|
|
72
|
+
# var yg beda dari default.
|
|
73
|
+
_PROVIDER_KEY_ENV = {
|
|
74
|
+
"deepseek": "DEEPSEEK_API_KEY",
|
|
75
|
+
"gmi": "GMI_API_KEY",
|
|
76
|
+
"openrouter": "OPENROUTER_API_KEY",
|
|
77
|
+
"anthropic": "ANTHROPIC_API_KEY",
|
|
78
|
+
"openai": "OPENAI_API_KEY",
|
|
79
|
+
"nous": "NOUS_API_KEY",
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
# default: deepseek (satu-satunya provider di project ini)
|
|
83
|
+
DEEPSEEK_MODEL = "deepseek-v4-pro"
|
|
84
|
+
DEEPSEEK_BASE = os.environ.get("SONNET_BASE_URL", "https://api.deepseek.com/v1")
|
|
85
|
+
# GMI Cloud (model abbrev "MiniMax" / provider gmi*) — endpoint
|
|
86
|
+
# yang bener: api.gmi-serving.com (bukan gmi-cloud.com — domain lama
|
|
87
|
+
# udah gak aktif & return 401 "Invalid token, failed to decode" buat
|
|
88
|
+
# key JWT yang sebenernya valid). FIX (02 Sep #11).
|
|
89
|
+
GMI_BASE = "https://api.gmi-serving.com/v1" # FIX (02 Sep #11): domain lama gmi-cloud.com udah 401, dipindah ke serving
|
|
90
|
+
|
|
91
|
+
# ── key derivation (obfuscated: split + reversed + xor) ──────────────────
|
|
92
|
+
# gak ada string key utuh di binary — di-assemble runtime dari potongan.
|
|
93
|
+
# FORMAT HARUS SAMA dengan scripts/encrypt_prompts.py:
|
|
94
|
+
# seed = reversed(parts) + "::" + parts
|
|
95
|
+
_SEED_A = ["s0nn3t", "k1nj1"]
|
|
96
|
+
_SEED_B = ["d4shb04rd", "x9f2"]
|
|
97
|
+
_XOR = 0x5A
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def _derive_key() -> bytes:
|
|
101
|
+
import hashlib
|
|
102
|
+
parts = _SEED_A + _SEED_B # x9f2, d4shb04rd, k1nj1, s0nn3t
|
|
103
|
+
seed = "".join(reversed(parts)) + "::" + "".join(parts)
|
|
104
|
+
return hashlib.sha256(seed.encode()).digest()
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def load_prompt(name: str) -> str:
|
|
108
|
+
"""Decrypt .bin prompt ke memory. Prompt gak pernah ke-tulis ke disk."""
|
|
109
|
+
try:
|
|
110
|
+
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
|
|
111
|
+
except ImportError:
|
|
112
|
+
return ""
|
|
113
|
+
p = PROMPTS / (name + ".bin")
|
|
114
|
+
if not p.exists():
|
|
115
|
+
return ""
|
|
116
|
+
raw = p.read_bytes()
|
|
117
|
+
nonce, ct = raw[:12], raw[12:]
|
|
118
|
+
try:
|
|
119
|
+
data = AESGCM(_derive_key()).decrypt(nonce, ct, b"sonnet-prompts-v1")
|
|
120
|
+
return data.decode("utf-8")
|
|
121
|
+
except Exception:
|
|
122
|
+
return ""
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class HermesSession:
|
|
126
|
+
"""Bungkus 1 sesi hermes agent: spawn subprocess, kirim prompt, stream reply.
|
|
127
|
+
|
|
128
|
+
Flow (ikutin userbot):
|
|
129
|
+
1. spawn hermes --cli dengan env (model, key, base_url)
|
|
130
|
+
2. pre-warm: tunggu prompt '> ' muncul
|
|
131
|
+
3. kirim pesan → baca stdout chunk-by-chunk → yield ke UI
|
|
132
|
+
"""
|
|
133
|
+
|
|
134
|
+
def __init__(self, api_key: str, model: str = DEEPSEEK_MODEL,
|
|
135
|
+
persona: str = "kinji", workdir: Path | None = None,
|
|
136
|
+
extra_system: str = "", max_tokens: int = 16384,
|
|
137
|
+
thinking: str = "medium", tavily_key: str = "",
|
|
138
|
+
profile: str | None = None,
|
|
139
|
+
provider: str = "deepseek",
|
|
140
|
+
base_url: str = "https://api.deepseek.com/v1",
|
|
141
|
+
api_mode: str = "chat_completions",
|
|
142
|
+
hermes_auth_dir: Path | None = None,
|
|
143
|
+
computer_use_enabled: bool = False):
|
|
144
|
+
self.api_key = api_key
|
|
145
|
+
self.model = model
|
|
146
|
+
self.persona = persona
|
|
147
|
+
self.workdir = workdir or Path.cwd()
|
|
148
|
+
self.extra_system = extra_system
|
|
149
|
+
self.max_tokens = max_tokens
|
|
150
|
+
self.thinking = thinking
|
|
151
|
+
self.tavily_key = tavily_key
|
|
152
|
+
self.profile = profile # Bot Mode: -p <nama> → profile hermes terisolasi
|
|
153
|
+
self.provider = provider
|
|
154
|
+
self.base_url = base_url
|
|
155
|
+
self.api_mode = api_mode
|
|
156
|
+
self.computer_use_enabled = computer_use_enabled
|
|
157
|
+
# FIX (04 Sep): sumber central token OAuth provider "hermes"
|
|
158
|
+
# (ditulis sekali oleh wizard login ke USERDATA/.hermes/auth.json).
|
|
159
|
+
# Dipakai _ensure_hermes_auth() buat sync ke HERMES_HOME AKTIF
|
|
160
|
+
# (yang sekarang selalu ikut workdir project user) — bukan buat
|
|
161
|
+
# maksa workdir pindah ke USERDATA kayak dulu (itu yang bikin
|
|
162
|
+
# "agent gak fokus di folder yang dipilih user").
|
|
163
|
+
self.hermes_auth_dir = hermes_auth_dir
|
|
164
|
+
self.proc: subprocess.Popen | None = None
|
|
165
|
+
self._out_queue: queue.Queue = queue.Queue()
|
|
166
|
+
self._thread: threading.Thread | None = None
|
|
167
|
+
|
|
168
|
+
# FIX (11 Sep #X): mapping "hermes" (slug UI) → "nous" (nama provider
|
|
169
|
+
# hermes CLI) tadinya cuma ada INLINE, diduplikat di 3 tempat beda
|
|
170
|
+
# (_ensure_hermes_config, _run_oneshot, spawn_gateway) — gampang jadi
|
|
171
|
+
# gak sinkron kalau salah satu diubah tapi yang lain kelupaan. Helper
|
|
172
|
+
# ini dipake buat caller BARU (per-request model/provider override di
|
|
173
|
+
# HermesGatewayClient.chat_stream, lihat gui_server.py._run_gateway_turn)
|
|
174
|
+
# biar nilai yang dikirim SELALU sama persis kayak yang ditulis
|
|
175
|
+
# _ensure_hermes_config() ke config.yaml — gak nambah tempat ke-4 yang
|
|
176
|
+
# bisa nyimpang.
|
|
177
|
+
def resolved_provider(self) -> str:
|
|
178
|
+
prov = (self.provider or "").lower().strip()
|
|
179
|
+
return "nous" if prov == "hermes" else prov
|
|
180
|
+
|
|
181
|
+
# ── prompt building (ngikutin userbot: system_prompt + bridge_prompt) ──
|
|
182
|
+
def build_system(self) -> str:
|
|
183
|
+
sp = load_prompt("system_prompt") # KINJI persona 45KB
|
|
184
|
+
bp = load_prompt("bridge_prompt") # BRIDGE_PROMPT 23KB
|
|
185
|
+
parts = [sp, bp]
|
|
186
|
+
if self.extra_system:
|
|
187
|
+
parts.append(self.extra_system)
|
|
188
|
+
# personality breach kalau dipilih
|
|
189
|
+
if self.persona == "breach":
|
|
190
|
+
try:
|
|
191
|
+
ps = json.loads(load_prompt("personalities"))
|
|
192
|
+
if "breach" in ps:
|
|
193
|
+
parts.append(ps["breach"].get("system_prompt", ""))
|
|
194
|
+
except Exception:
|
|
195
|
+
pass
|
|
196
|
+
return "\n\n".join(p for p in parts if p)
|
|
197
|
+
|
|
198
|
+
def _ensure_soul(self):
|
|
199
|
+
"""Tulis persona ke HERMES_HOME/SOUL.md — hermes auto-inject
|
|
200
|
+
SOUL.md dari HERMES_HOME tiap start (identity slot #1, "always
|
|
201
|
+
included when present"). ini yang bikin prompt KINJI (45KB
|
|
202
|
+
persona + 23KB bridge) beneran ke-load."""
|
|
203
|
+
try:
|
|
204
|
+
sp = load_prompt("system_prompt")
|
|
205
|
+
bp = load_prompt("bridge_prompt")
|
|
206
|
+
if not (sp or bp):
|
|
207
|
+
print("SOUL: prompts kosong — skip", flush=True)
|
|
208
|
+
return
|
|
209
|
+
soul = ("# sonnet identity\n\n" + sp + "\n\n" + bp
|
|
210
|
+
if sp else bp)
|
|
211
|
+
hdir = _hermes_home(self.workdir) # HERMES_HOME
|
|
212
|
+
hdir.mkdir(parents=True, exist_ok=True)
|
|
213
|
+
p = hdir / "SOUL.md"
|
|
214
|
+
p.write_text(soul, encoding="utf-8")
|
|
215
|
+
print(f"SOUL.md ditulis: {p} ({len(soul)} chars)", flush=True)
|
|
216
|
+
except Exception as e:
|
|
217
|
+
print("SOUL write error: %r" % (e,), flush=True)
|
|
218
|
+
|
|
219
|
+
def _tools_flag(self) -> str:
|
|
220
|
+
"""Build -t flag value based on config. computer_use cuma included
|
|
221
|
+
kalau di-enable di Settings UI."""
|
|
222
|
+
base = "skills,memory,web,todo,session_search,terminal,file,browser,cronjob,delegation,vision,image_gen,tts,code_execution,kanban,clarify"
|
|
223
|
+
if getattr(self, "computer_use_enabled", False):
|
|
224
|
+
base += ",computer_use"
|
|
225
|
+
return base
|
|
226
|
+
|
|
227
|
+
def _ensure_skills(self):
|
|
228
|
+
"""FIX (01 Sep): extract skill pack ke HERMES_HOME/skills/ pas
|
|
229
|
+
first-run (kalo kosong). Skill pack (999 skill) di-bundle di
|
|
230
|
+
backend/skills_pack.zip — user Windows gak punya akses ke repo
|
|
231
|
+
kita, jadi harus ke-seed dari installer."""
|
|
232
|
+
import zipfile
|
|
233
|
+
try:
|
|
234
|
+
hdir = _hermes_home(self.workdir)
|
|
235
|
+
skills_dir = hdir / "skills"
|
|
236
|
+
# Sudah ke-seed penuh? Cek JUMLAH, bukan "ada": seed
|
|
237
|
+
# sebelumnya bisa ketinggal terputus (crash / disk penuh /
|
|
238
|
+
# versi lama) dan `any()`bakal lolos dengan 58 dari 973.
|
|
239
|
+
# 973 = jumlah project skill di pack ini; pakai ambang
|
|
240
|
+
# konservatif supaya partial seed di Heal ulang.
|
|
241
|
+
EXPECTED = 900
|
|
242
|
+
have = (len(list(skills_dir.rglob("SKILL.md")))
|
|
243
|
+
if skills_dir.is_dir() else 0)
|
|
244
|
+
if have >= EXPECTED:
|
|
245
|
+
return
|
|
246
|
+
pack = BASE / "skills_pack.zip" # di backend/ (frozen: exe dir)
|
|
247
|
+
if not pack.exists():
|
|
248
|
+
# distribution pip/git: skill pack ada sebagai direktori
|
|
249
|
+
# (sonnet_data/skills) atau .hermes/skills, bukan zip.
|
|
250
|
+
if SKILLS_SRC.is_dir() and any(
|
|
251
|
+
SKILLS_SRC.rglob("SKILL.md")):
|
|
252
|
+
if have:
|
|
253
|
+
# heal: buang sisa partial biar file basi
|
|
254
|
+
# (skill yg dihapus di versi baru) gak nempel
|
|
255
|
+
import shutil as _sh
|
|
256
|
+
_sh.rmtree(skills_dir, ignore_errors=True)
|
|
257
|
+
skills_dir.mkdir(parents=True, exist_ok=True)
|
|
258
|
+
n = 0
|
|
259
|
+
for src in SKILLS_SRC.rglob("SKILL.md"):
|
|
260
|
+
rel = src.relative_to(SKILLS_SRC)
|
|
261
|
+
dst = skills_dir / rel
|
|
262
|
+
dst.parent.mkdir(parents=True, exist_ok=True)
|
|
263
|
+
dst.write_bytes(src.read_bytes())
|
|
264
|
+
n += 1
|
|
265
|
+
print(f"SKILLS: {n} skill di-seed dari "
|
|
266
|
+
f"{SKILLS_SRC}", flush=True)
|
|
267
|
+
return
|
|
268
|
+
print("SKILLS: gak ada skills_pack.zip atau "
|
|
269
|
+
"sonnet_data/skills — skip", flush=True)
|
|
270
|
+
return
|
|
271
|
+
skills_dir.mkdir(parents=True, exist_ok=True)
|
|
272
|
+
with zipfile.ZipFile(pack) as z:
|
|
273
|
+
# zip berisi prefix "skills/..." → strip biar extract
|
|
274
|
+
# langsung ke skills_dir (bukan skills/skills)
|
|
275
|
+
# FIX (11 Sep): zip sekarang tanpa prefix skills/ — cek dulu
|
|
276
|
+
has_prefix = any(n.startswith("skills/") for n in z.namelist())
|
|
277
|
+
for member in z.namelist():
|
|
278
|
+
if has_prefix and member.startswith("skills/"):
|
|
279
|
+
member = member[len("skills/"):]
|
|
280
|
+
if not member:
|
|
281
|
+
continue
|
|
282
|
+
target = skills_dir / member
|
|
283
|
+
if member.endswith("/"):
|
|
284
|
+
target.mkdir(parents=True, exist_ok=True)
|
|
285
|
+
continue
|
|
286
|
+
try:
|
|
287
|
+
target.parent.mkdir(parents=True, exist_ok=True)
|
|
288
|
+
# Baca dari zip — pake nama asli (dengan prefix kalo ada)
|
|
289
|
+
orig = "skills/" + member if has_prefix else member
|
|
290
|
+
target.write_bytes(z.read(orig))
|
|
291
|
+
except Exception:
|
|
292
|
+
pass
|
|
293
|
+
n = len(list(skills_dir.rglob("SKILL.md")))
|
|
294
|
+
print(f"SKILLS: extracted {n} skills ke {skills_dir}", flush=True)
|
|
295
|
+
# FIX (10 Sep): setelah extract, tulis apikey.json untuk tavily-search
|
|
296
|
+
# biar skill bisa langsung dipake tanpa user input ulang di workdir baru.
|
|
297
|
+
# JANGAN overwrite kalau udah ada (user mungkin udah punya key sendiri).
|
|
298
|
+
if self.tavily_key:
|
|
299
|
+
tavily_skill_dir = skills_dir / "web" / "tavily-search"
|
|
300
|
+
apikey_path = tavily_skill_dir / "apikey.json"
|
|
301
|
+
if tavily_skill_dir.exists() and not apikey_path.exists():
|
|
302
|
+
try:
|
|
303
|
+
import json as _json
|
|
304
|
+
apikey_path.write_text(
|
|
305
|
+
_json.dumps({"tavily_api_key": self.tavily_key}, indent=2),
|
|
306
|
+
encoding="utf-8")
|
|
307
|
+
print(f"SKILLS: apikey.json ditulis ke {apikey_path}", flush=True)
|
|
308
|
+
except Exception:
|
|
309
|
+
pass
|
|
310
|
+
except Exception as e:
|
|
311
|
+
print("SKILLS extract error: %r" % (e,), flush=True)
|
|
312
|
+
|
|
313
|
+
def _ensure_hermes_auth(self):
|
|
314
|
+
"""provider 'hermes' (CLI: 'nous') pakai OAuth — token cuma pernah
|
|
315
|
+
ditulis SEKALI ke lokasi central (USERDATA/.hermes/auth.json) pas
|
|
316
|
+
login lewat wizard (lihat handle_hermes_oauth_start di gui_server).
|
|
317
|
+
HERMES_HOME sekarang SELALU ikut self.workdir (folder project user
|
|
318
|
+
yang dipilih lewat tombol folder) — bukan dipaksa balik ke USERDATA
|
|
319
|
+
kayak versi lama. Supaya hermes CLI tetep nemu token-nya di
|
|
320
|
+
HERMES_HOME aktif itu, copy token dari sumber central ke situ tiap
|
|
321
|
+
spawn/kirim pesan (bukan mindahin workdir-nya)."""
|
|
322
|
+
# Provider slug di CLI = "nous"; GUI desktop pernah pakai
|
|
323
|
+
# "hermes". Terima keduanya — kalau cuma cek "hermes", token
|
|
324
|
+
# OAuth Portal nggak pernah di-sync ke HERMES_HOME aktif dan
|
|
325
|
+
# chat oneshot mati diam dengan "credentials or agent init
|
|
326
|
+
# failed".
|
|
327
|
+
if (self.provider or "").lower() not in ("hermes", "nous") \
|
|
328
|
+
or not self.hermes_auth_dir:
|
|
329
|
+
return
|
|
330
|
+
try:
|
|
331
|
+
src = Path(self.hermes_auth_dir) / "auth.json"
|
|
332
|
+
if not src.exists():
|
|
333
|
+
return # belum pernah login — biarin hermes CLI yang teriak
|
|
334
|
+
dst_dir = _hermes_home(self.workdir)
|
|
335
|
+
dst_dir.mkdir(parents=True, exist_ok=True)
|
|
336
|
+
dst = dst_dir / "auth.json"
|
|
337
|
+
if not dst.exists() or src.stat().st_mtime > dst.stat().st_mtime:
|
|
338
|
+
import shutil
|
|
339
|
+
shutil.copy2(src, dst)
|
|
340
|
+
print(f"hermes auth synced ke {dst}", flush=True)
|
|
341
|
+
except Exception as e:
|
|
342
|
+
print("hermes auth sync error: %r" % (e,), flush=True)
|
|
343
|
+
|
|
344
|
+
def spawn(self):
|
|
345
|
+
# ── Windows: one-shot mode — hermes chat -q gak butuh TTY
|
|
346
|
+
# (winpty/pipe terbukti gagal). spawn() cuma prepare; tiap
|
|
347
|
+
# chat = 1 subprocess hermes chat -q ... -Q (quiet). ──
|
|
348
|
+
if os.name == "nt":
|
|
349
|
+
self._oneshot = True
|
|
350
|
+
# jangan reset session_id kalau udah ada (konteks chat lanjut)
|
|
351
|
+
if not hasattr(self, "session_id"):
|
|
352
|
+
self.session_id = None
|
|
353
|
+
self._ensure_soul()
|
|
354
|
+
self._ensure_skills() # FIX (01 Sep): seed skill pack first-run
|
|
355
|
+
# FIX (31 Agu): _ensure_hermes_config WAJIB dipanggil di Windows
|
|
356
|
+
# juga — dulu cuma di jalur Linux, makanya config.yaml gak pernah
|
|
357
|
+
# ke-tulis api_key → hermes bilang "no API keys or providers
|
|
358
|
+
# found → run setup?" → chat gak dibalas.
|
|
359
|
+
self._ensure_hermes_config()
|
|
360
|
+
self._ensure_hermes_auth() # FIX (04 Sep): sync token OAuth ke HERMES_HOME aktif
|
|
361
|
+
return
|
|
362
|
+
self._oneshot = False
|
|
363
|
+
self._ensure_soul()
|
|
364
|
+
self._ensure_skills() # FIX (01 Sep): seed skill pack first-run
|
|
365
|
+
env = os.environ.copy()
|
|
366
|
+
# FIX (11 Sep): tambahin folder cua + runtime/Scripts ke PATH biar
|
|
367
|
+
# hermes CLI bisa nemu cua-computer-server.exe
|
|
368
|
+
base = Path(__file__).resolve().parent.parent
|
|
369
|
+
cua_dir = str(base / "cua")
|
|
370
|
+
runtime_dir = str(base / "runtime")
|
|
371
|
+
runtime_scripts = str(base / "runtime" / "Scripts")
|
|
372
|
+
# FIX: tambahin juga path cua-driver yang di-install hermes
|
|
373
|
+
cua_driver_path = str(Path.home() / "AppData" / "Local" / "Programs" / "Cua" / "cua-driver" / "bin")
|
|
374
|
+
env["PATH"] = cua_dir + os.pathsep + runtime_dir + os.pathsep + runtime_scripts + os.pathsep + cua_driver_path + os.pathsep + env.get("PATH", "")
|
|
375
|
+
# bikin .hermes/config.yaml otomatis dari template (isi api_key)
|
|
376
|
+
self._ensure_hermes_config()
|
|
377
|
+
self._ensure_hermes_auth() # FIX (04 Sep): sync token OAuth ke HERMES_HOME aktif
|
|
378
|
+
env.update({
|
|
379
|
+
# HOME ga di-override: Hermes hormat HERMES_HOME, dan
|
|
380
|
+
# memaksa HOME ke workdir bikin auth global user
|
|
381
|
+
# (~/.hermes/auth.json untuk Portal OAuth) gak ketemu —
|
|
382
|
+
# gejalanya oneshot diam tanpa error. Dulu HOME di-paksa
|
|
383
|
+
# karena .hermes masih di workdir/.hermes; sekarang
|
|
384
|
+
# HERMES_HOME yg dipisah dari workdir.
|
|
385
|
+
"HERMES_HOME": str(_hermes_home(self.workdir)),
|
|
386
|
+
"TERMINAL_CWD": str(self.workdir),
|
|
387
|
+
"UB_MODEL": self.model,
|
|
388
|
+
"UB_API_KEY": self.api_key,
|
|
389
|
+
# FIX (02 Sep #12): dulu base_url ditebak dari substring nama
|
|
390
|
+
# model ("MiniMax" di nama → GMI, selain itu → DeepSeek) —
|
|
391
|
+
# gak nyambung sama registry per-provider (self.base_url/
|
|
392
|
+
# self.provider, hasil resolve dari model yang lagi aktif di
|
|
393
|
+
# /api/models). Sekarang pake self.base_url langsung, dan
|
|
394
|
+
# DEEPSEEK_API_KEY cuma di-set kalau provider aktifnya emang
|
|
395
|
+
# deepseek — biar gak nabrak provider lain kayak GMI (lihat
|
|
396
|
+
# komentar sama di _run_oneshot, jalur Windows).
|
|
397
|
+
"UB_BASE_URL": getattr(self, "base_url", None) or DEEPSEEK_BASE,
|
|
398
|
+
"PYTHONDONTWRITEBYTECODE": "1",
|
|
399
|
+
# UTF-8 mode: python pake utf-8 buat semua io, gak peduli
|
|
400
|
+
# locale Windows (cp1252) → write_text gak bakal UnicodeEncodeError
|
|
401
|
+
"PYTHONUTF8": "1",
|
|
402
|
+
# defer agent startup (kayak userbot): hermes CLI cepet muncul,
|
|
403
|
+
# agent baru ke-init pas pesan pertama → first-turn gak 2-3 menit
|
|
404
|
+
"HERMES_DEFER_AGENT_STARTUP": "1",
|
|
405
|
+
})
|
|
406
|
+
# FIX (02 Sep #13): sama kayak _run_oneshot — provider → env var
|
|
407
|
+
# mapping generik, bukan hardcoded deepseek doang.
|
|
408
|
+
_prov_lx = (getattr(self, "provider", "") or "").lower().strip()
|
|
409
|
+
# FIX (03 Sep): provider "hermes" (UI slug) → "nous" (hermes CLI
|
|
410
|
+
# provider name). hermes CLI gak recognize "hermes" sebagai provider.
|
|
411
|
+
if _prov_lx == "hermes":
|
|
412
|
+
_prov_lx = "nous"
|
|
413
|
+
if not _prov_lx:
|
|
414
|
+
env["DEEPSEEK_API_KEY"] = self.api_key
|
|
415
|
+
else:
|
|
416
|
+
_key_env = _PROVIDER_KEY_ENV.get(_prov_lx, f"{_prov_lx.upper()}_API_KEY")
|
|
417
|
+
env[_key_env] = self.api_key
|
|
418
|
+
if self.tavily_key:
|
|
419
|
+
# web search (tavily) — hermes baca TAVILY_API_KEY buat web_search
|
|
420
|
+
env["TAVILY_API_KEY"] = self.tavily_key
|
|
421
|
+
if self.thinking:
|
|
422
|
+
env["UB_REASONING_EFFORT"] = self.thinking
|
|
423
|
+
env["REASONING_EFFORT"] = self.thinking
|
|
424
|
+
# hermes CLI: cek ketersediaan
|
|
425
|
+
hermes = self._find_hermes()
|
|
426
|
+
cmd = [hermes, "--cli", "--no-restore-cwd", "--yolo",
|
|
427
|
+
"-t", self._tools_flag()]
|
|
428
|
+
# ── Bot Mode: insert -p <profile> (baca profile terisolasi di
|
|
429
|
+
# HERMES_HOME/profiles/<nama>/), kalo profile-nya ada.
|
|
430
|
+
if self.profile:
|
|
431
|
+
prof_dir = _hermes_home(self.workdir) / "profiles" / self.profile
|
|
432
|
+
if prof_dir.exists():
|
|
433
|
+
cmd[1:1] = ["-p", self.profile]
|
|
434
|
+
# ── WAJIB PTY: hermes --cli gak jalan lewat pipe biasa.
|
|
435
|
+
# Linux: pakai tmux (kayak userbot produksi — TERBUKTI JALAN).
|
|
436
|
+
# Windows: ConPTY via winpty kalau ada, atau pipe biasa.
|
|
437
|
+
if os.name == "posix" and self._have_tmux():
|
|
438
|
+
self._spawn_tmux(cmd, env)
|
|
439
|
+
elif os.name == "posix":
|
|
440
|
+
self._spawn_pty(cmd, env)
|
|
441
|
+
else:
|
|
442
|
+
self._spawn_pipe(cmd, env)
|
|
443
|
+
|
|
444
|
+
def _have_tmux(self) -> bool:
|
|
445
|
+
import shutil
|
|
446
|
+
return shutil.which("tmux") is not None
|
|
447
|
+
|
|
448
|
+
def _spawn_tmux(self, cmd, env):
|
|
449
|
+
"""Spawn hermes di tmux session (persistent, PTY beneran).
|
|
450
|
+
Output di-pipe ke file log via `tmux pipe-pane` — stream asli
|
|
451
|
+
(delta), bukan snapshot capture-pane (yang bikin duplikat)."""
|
|
452
|
+
import uuid
|
|
453
|
+
self._tmux_name = "sonnet_" + uuid.uuid4().hex[:8]
|
|
454
|
+
self._logfile = f"/tmp/{self._tmux_name}.log"
|
|
455
|
+
cwd = str(self.workdir)
|
|
456
|
+
# env inline: HOME, HERMES_HOME, UB_*, DEEPSEEK_API_KEY
|
|
457
|
+
envline = " ".join(f"{k}={shlex.quote(v)}" for k, v in env.items()
|
|
458
|
+
if k.startswith(("HOME", "HERMES", "UB_", "DEEPSEEK",
|
|
459
|
+
"PYTHON", "TAVILY", "TERMINAL")))
|
|
460
|
+
inner = f"cd {shlex.quote(cwd)} && env {envline} " + " ".join(shlex.quote(c) for c in cmd)
|
|
461
|
+
subprocess.run(["tmux", "new-session", "-d", "-s", self._tmux_name,
|
|
462
|
+
"-x", "200", "-y", "50", inner], check=False)
|
|
463
|
+
# pipe output pane ke file (stream asli, ANSI + semua)
|
|
464
|
+
subprocess.run(["tmux", "pipe-pane", "-t", self._tmux_name,
|
|
465
|
+
"-o", f"cat >> {self._logfile}"], check=False)
|
|
466
|
+
self._out_queue = queue.Queue()
|
|
467
|
+
self._thread = threading.Thread(target=self._tmux_reader, daemon=True)
|
|
468
|
+
self._thread.start()
|
|
469
|
+
self.proc = None # dikelola tmux
|
|
470
|
+
|
|
471
|
+
def _tmux_reader(self):
|
|
472
|
+
"""Baca stream pane dari logfile (offset-based, delta asli)."""
|
|
473
|
+
offset = 0
|
|
474
|
+
while True:
|
|
475
|
+
try:
|
|
476
|
+
try:
|
|
477
|
+
sz = os.path.getsize(self._logfile)
|
|
478
|
+
except OSError:
|
|
479
|
+
time.sleep(0.4)
|
|
480
|
+
continue
|
|
481
|
+
if sz > offset:
|
|
482
|
+
with open(self._logfile, "r", encoding="utf-8",
|
|
483
|
+
errors="replace") as f:
|
|
484
|
+
f.seek(offset)
|
|
485
|
+
self._out_queue.put(f.read())
|
|
486
|
+
offset = f.tell()
|
|
487
|
+
time.sleep(0.3)
|
|
488
|
+
except Exception:
|
|
489
|
+
time.sleep(1)
|
|
490
|
+
|
|
491
|
+
def _spawn_pty(self, cmd, env):
|
|
492
|
+
import pty
|
|
493
|
+
import fcntl
|
|
494
|
+
import termios
|
|
495
|
+
import struct
|
|
496
|
+
master, slave = pty.openpty()
|
|
497
|
+
fcntl.ioctl(slave, termios.TIOCSWINSZ, struct.pack("HHHH", 50, 200, 0, 0))
|
|
498
|
+
self.proc = subprocess.Popen(
|
|
499
|
+
cmd,
|
|
500
|
+
stdin=slave, stdout=slave, stderr=slave,
|
|
501
|
+
text=True, encoding="utf-8", errors="replace",
|
|
502
|
+
env=env, cwd=str(self.workdir), close_fds=True,
|
|
503
|
+
)
|
|
504
|
+
os.close(slave)
|
|
505
|
+
self._pty_master = master
|
|
506
|
+
self._thread = threading.Thread(target=self._reader_pty, daemon=True)
|
|
507
|
+
self._thread.start()
|
|
508
|
+
|
|
509
|
+
def _spawn_pipe(self, cmd, env):
|
|
510
|
+
# ── Windows: hermes --cli WAJIB TTY — pipe biasa bikin hermes
|
|
511
|
+
# nolak interaktif ("No interactive TTY detected") → chat gak
|
|
512
|
+
# dijawab. pake winpty/ConPTY (bundled di runtime/) dulu.
|
|
513
|
+
print("spawn windows: cmd=" + " ".join(cmd), flush=True)
|
|
514
|
+
try:
|
|
515
|
+
from winpty import PtyProcess
|
|
516
|
+
self._winpty = PtyProcess.spawn(
|
|
517
|
+
cmd, cwd=str(self.workdir), env=env, dimensions=(50, 200))
|
|
518
|
+
self._thread = threading.Thread(target=self._reader_winpty,
|
|
519
|
+
daemon=True)
|
|
520
|
+
self._thread.start()
|
|
521
|
+
print("spawn OK via winpty", flush=True)
|
|
522
|
+
return
|
|
523
|
+
except Exception as e:
|
|
524
|
+
print("winpty gagal: %r — fallback pipe" % (e,), flush=True)
|
|
525
|
+
self._winpty = None
|
|
526
|
+
self.proc = subprocess.Popen(
|
|
527
|
+
cmd,
|
|
528
|
+
stdin=subprocess.PIPE,
|
|
529
|
+
stdout=subprocess.PIPE,
|
|
530
|
+
stderr=subprocess.STDOUT,
|
|
531
|
+
text=True,
|
|
532
|
+
encoding="utf-8",
|
|
533
|
+
errors="replace",
|
|
534
|
+
env=env,
|
|
535
|
+
cwd=str(self.workdir),
|
|
536
|
+
bufsize=1,
|
|
537
|
+
)
|
|
538
|
+
self._thread = threading.Thread(target=self._reader, daemon=True)
|
|
539
|
+
self._thread.start()
|
|
540
|
+
|
|
541
|
+
def _reader_winpty(self):
|
|
542
|
+
while True:
|
|
543
|
+
try:
|
|
544
|
+
data = self._winpty.read(4096)
|
|
545
|
+
if not data:
|
|
546
|
+
print("winpty reader EOF — process mati/keluar", flush=True)
|
|
547
|
+
break
|
|
548
|
+
self._out_queue.put(data)
|
|
549
|
+
except Exception as e:
|
|
550
|
+
print("winpty reader error: %r" % (e,), flush=True)
|
|
551
|
+
break
|
|
552
|
+
|
|
553
|
+
def _find_hermes(self) -> str:
|
|
554
|
+
return find_hermes_binary()
|
|
555
|
+
|
|
556
|
+
def _ensure_hermes_config(self):
|
|
557
|
+
"""Bikin .hermes/config.yaml dari template, isi api_key dari self.api_key.
|
|
558
|
+
Kalau template gak ada (bundle rusak) → fallback config minimal,
|
|
559
|
+
biar hermes gak nolak start ("no API keys or providers found").
|
|
560
|
+
File yang ADA TAPI KOSONG (hermes nge-init config kosong pas
|
|
561
|
+
pertama start) juga di-repair → tulis ulang template."""
|
|
562
|
+
hdir = _hermes_home(self.workdir)
|
|
563
|
+
hdir.mkdir(parents=True, exist_ok=True)
|
|
564
|
+
cfg_path = hdir / "config.yaml"
|
|
565
|
+
txt = ""
|
|
566
|
+
if cfg_path.exists():
|
|
567
|
+
try:
|
|
568
|
+
txt = cfg_path.read_text(encoding="utf-8", errors="replace")
|
|
569
|
+
except Exception:
|
|
570
|
+
txt = ""
|
|
571
|
+
if not txt.strip() or "model:" not in txt:
|
|
572
|
+
tpl = BASE / "hermes_config_template.yaml"
|
|
573
|
+
if tpl.exists():
|
|
574
|
+
# WAJIB encoding utf-8 — template ada karakter non-ASCII
|
|
575
|
+
# (em-dash —) yang gagal di-encode pake cp1252 Windows
|
|
576
|
+
cfg_path.write_text(tpl.read_text(encoding="utf-8"),
|
|
577
|
+
encoding="utf-8")
|
|
578
|
+
else:
|
|
579
|
+
cfg_path.write_text(
|
|
580
|
+
"model:\n"
|
|
581
|
+
" default: deepseek-v4-pro\n"
|
|
582
|
+
" provider: deepseek\n"
|
|
583
|
+
" base_url: https://api.deepseek.com/v1\n"
|
|
584
|
+
" api_key: \"\"\n"
|
|
585
|
+
" max_tokens: 16384\n"
|
|
586
|
+
" api_mode: chat_completions\n"
|
|
587
|
+
"agent:\n"
|
|
588
|
+
" max_turns: 150\n"
|
|
589
|
+
" verify_on_stop: true\n"
|
|
590
|
+
" reasoning_effort: medium\n"
|
|
591
|
+
"terminal:\n"
|
|
592
|
+
" backend: local\n"
|
|
593
|
+
" timeout: 60\n"
|
|
594
|
+
" home_mode: false\n"
|
|
595
|
+
"web:\n"
|
|
596
|
+
" backend: curl\n"
|
|
597
|
+
"display:\n"
|
|
598
|
+
" show_reasoning: true\n"
|
|
599
|
+
" streaming: true\n"
|
|
600
|
+
" compact: true\n", encoding="utf-8")
|
|
601
|
+
print(f"config.yaml di-repair: {cfg_path} "
|
|
602
|
+
f"({cfg_path.stat().st_size} bytes)", flush=True)
|
|
603
|
+
# isi api_key + model/provider/base_url (selalu update ke session
|
|
604
|
+
# ini — biar gak ke-pake key/model lama dari config sebelumnya)
|
|
605
|
+
#
|
|
606
|
+
# FIX (11 Sep #18): BUG BESAR — implementasi lama mutasi config.yaml
|
|
607
|
+
# pake serangkaian re.sub() di TEKS MENTAH, bukan parse YAML beneran.
|
|
608
|
+
# Dua masalah independen, dan KOMBINASI keduanya yang bikin "chat
|
|
609
|
+
# jawab kosong, ctx_used=0":
|
|
610
|
+
# 1) Regex-nya UNANCHORED & tanpa count=1 — re.sub(r"default:\s*\S+",
|
|
611
|
+
# ...) misalnya nyari literal "default:" DI MANA AJA di file
|
|
612
|
+
# (bukan cuma di bawah `model:`), dan kalau kebetulan match >1
|
|
613
|
+
# kali, SEMUA ketiban value yang sama. Gak ada satupun langkah
|
|
614
|
+
# yang validasi hasilnya masih YAML valid.
|
|
615
|
+
# 2) Begitu hasilnya kebetulan syntactically invalid (kombinasi
|
|
616
|
+
# value tertentu — nggak harus dari 1 baris yang "kelihatan
|
|
617
|
+
# salah" sendirian), file KETULIS ke disk apa adanya. hermes
|
|
618
|
+
# gateway gagal parse config.yaml pas start ("mapping values
|
|
619
|
+
# are not allowed here") → fallback ke default bawaan hermes-
|
|
620
|
+
# agent (provider `nous` lewat auto-detect chain internalnya,
|
|
621
|
+
# TANPA model) — SEMUA override di bawah ini (termasuk
|
|
622
|
+
# provider/model yang mau kita pasang) diabaikan total oleh
|
|
623
|
+
# hermes. Provider nous kepanggil tanpa model → API balikin
|
|
624
|
+
# 400 "Model parameter is required" → non-retryable → turn
|
|
625
|
+
# kelar TANPA assistant.delta apapun. Endpoint
|
|
626
|
+
# /api/sessions/{id}/chat/stream cuma janji event
|
|
627
|
+
# assistant.delta/tool.started/tool.completed/run.completed
|
|
628
|
+
# (gak ada event error terpisah di dokumentasi resminya), jadi
|
|
629
|
+
# run.completed yang kosong itu ke-terima apa adanya sebagai
|
|
630
|
+
# "turn sukses tanpa isi" — persis gejala di backend.log.
|
|
631
|
+
#
|
|
632
|
+
# FIX: parse config.yaml jadi dict BENERAN (yaml.safe_load), mutasi
|
|
633
|
+
# AS DATA (bukan string), yaml.safe_dump ulang. Dump dari dict
|
|
634
|
+
# SELALU syntactically valid apapun isi value-nya — termasuk yang
|
|
635
|
+
# ada titik dua di tengah kayak "meituan/longcat-2.0:free" (valid
|
|
636
|
+
# sebenernya secara YAML, tapi sekarang gak lagi tergantung regex
|
|
637
|
+
# nebak-nebak buat mastiin). Kalau file yang ADA di disk gagal
|
|
638
|
+
# diparse (mis. korup dari sebelum fix ini di-deploy), jangan coba
|
|
639
|
+
# tambal teks yang udah rusak — mulai dari template bersih dulu,
|
|
640
|
+
# baru tumpuk override di atasnya. Ditutup dengan re-parse hasil
|
|
641
|
+
# dump SEBELUM ditulis ke disk: kalau tetep gagal (harusnya gak
|
|
642
|
+
# pernah kejadian), batalin write daripada nimpa config yang masih
|
|
643
|
+
# hidup dengan sesuatu yang mungkin lebih rusak.
|
|
644
|
+
#
|
|
645
|
+
# DEPENDENCY BARU: butuh `pyyaml` (import yaml) di environment yang
|
|
646
|
+
# menjalankan gui_server.py/agent_core.py — sebelumnya file ini gak
|
|
647
|
+
# pernah beneran parse YAML, cuma regex di string. Kalau belum ada:
|
|
648
|
+
# pip install pyyaml (atau pip install pyyaml --break-system-packages
|
|
649
|
+
# tergantung environment-nya).
|
|
650
|
+
import yaml
|
|
651
|
+
try:
|
|
652
|
+
try:
|
|
653
|
+
cfg = yaml.safe_load(cfg_path.read_text(encoding="utf-8")) or {}
|
|
654
|
+
if not isinstance(cfg, dict):
|
|
655
|
+
raise ValueError("root config.yaml bukan mapping")
|
|
656
|
+
except Exception as e:
|
|
657
|
+
print(f"config.yaml gak valid ({e!r}) — rebuild dari "
|
|
658
|
+
f"template sebelum apply override user", flush=True)
|
|
659
|
+
tpl = BASE / "hermes_config_template.yaml"
|
|
660
|
+
base_txt = tpl.read_text(encoding="utf-8") if tpl.exists() else (
|
|
661
|
+
"model:\n default: deepseek-v4-pro\n provider: deepseek\n"
|
|
662
|
+
" base_url: https://api.deepseek.com/v1\n api_key: \"\"\n"
|
|
663
|
+
" max_tokens: 16384\n api_mode: chat_completions\n"
|
|
664
|
+
"agent:\n max_turns: 150\n verify_on_stop: true\n"
|
|
665
|
+
" reasoning_effort: medium\n")
|
|
666
|
+
cfg = yaml.safe_load(base_txt) or {}
|
|
667
|
+
cfg.setdefault("model", {})
|
|
668
|
+
cfg.setdefault("agent", {})
|
|
669
|
+
cfg.setdefault("display", {})
|
|
670
|
+
|
|
671
|
+
# FIX (02 Sep #5): show_reasoning di-force TRUE — dulu false,
|
|
672
|
+
# yang bikin hermes verbose (-v) nge-print reasoning MENTAH
|
|
673
|
+
# "[thinking] ..." polos ke stdout → bocor ke chat.
|
|
674
|
+
if cfg["display"].get("show_reasoning") is False:
|
|
675
|
+
cfg["display"]["show_reasoning"] = True
|
|
676
|
+
print("config: show_reasoning di-force true", flush=True)
|
|
677
|
+
|
|
678
|
+
# FIX (05 Sep #17): reasoning_effort ikut dropdown "thinking" —
|
|
679
|
+
# jalur gateway (yang beneran aktif buat chat GUI) cuma baca
|
|
680
|
+
# dari config.yaml ini, env var UB_REASONING_EFFORT gak dipake
|
|
681
|
+
# spawn_gateway().
|
|
682
|
+
think_val = getattr(self, "thinking", None)
|
|
683
|
+
if think_val:
|
|
684
|
+
cfg["agent"]["reasoning_effort"] = think_val
|
|
685
|
+
print(f"config: reasoning_effort → {think_val}", flush=True)
|
|
686
|
+
|
|
687
|
+
# FIX (11 Sep): toggle computer_use — gateway resolve toolset
|
|
688
|
+
# dari config.yaml agent.disabled_toolsets (default-ALLOW semua
|
|
689
|
+
# KECUALI yang di-deny di situ), bukan dari -t/--toolsets CLI
|
|
690
|
+
# (itu cuma berlaku buat -z/--oneshot dan --tui, gak ke `gateway`).
|
|
691
|
+
if not getattr(self, "computer_use_enabled", False):
|
|
692
|
+
cfg["agent"]["disabled_toolsets"] = ["computer_use"]
|
|
693
|
+
print("config: disabled_toolsets → [computer_use]", flush=True)
|
|
694
|
+
else:
|
|
695
|
+
cfg["agent"].pop("disabled_toolsets", None)
|
|
696
|
+
|
|
697
|
+
# model aktif (default) — dari self.model (BRIDGE.cfg), bukan
|
|
698
|
+
# force ke deepseek-v4-pro: user bisa pilih model GMI dll.
|
|
699
|
+
model_val = getattr(self, "model", None) or "deepseek-v4-pro"
|
|
700
|
+
cfg["model"]["default"] = model_val
|
|
701
|
+
print(f"config: default → {model_val}", flush=True)
|
|
702
|
+
|
|
703
|
+
# provider + base_url + api_mode (biar endpoint custom kaya
|
|
704
|
+
# GMI/OpenRouter ke-detect; fallback deepseek)
|
|
705
|
+
prov = getattr(self, "provider", "") or ""
|
|
706
|
+
base = getattr(self, "base_url", "") or ""
|
|
707
|
+
amode = getattr(self, "api_mode", "") or ""
|
|
708
|
+
# FIX (03 Sep): provider "hermes" (UI slug) → "nous" (hermes CLI
|
|
709
|
+
# provider name) — sama persis kayak resolved_provider() di atas.
|
|
710
|
+
if prov == "hermes":
|
|
711
|
+
prov = "nous"
|
|
712
|
+
base = base or "https://inference-api.nousresearch.com/v1"
|
|
713
|
+
if prov:
|
|
714
|
+
cfg["model"]["provider"] = prov
|
|
715
|
+
if base:
|
|
716
|
+
cfg["model"]["base_url"] = base
|
|
717
|
+
if amode:
|
|
718
|
+
cfg["model"]["api_mode"] = amode
|
|
719
|
+
cfg["model"]["api_key"] = self.api_key
|
|
720
|
+
|
|
721
|
+
# ── FIX (01 Sep): anti-bug hermes v0.21 — versi-agnostic, aman
|
|
722
|
+
# di semua versi (field yang gak dikenal di versi lama cuma
|
|
723
|
+
# di-ignore). 1) paste collapse v0.21 motong prompt panjang →
|
|
724
|
+
# model echo → reply ilang; 2) context_file_max_chars 20K →
|
|
725
|
+
# SOUL.md 53K kepotong tengah → persona plenger.
|
|
726
|
+
cfg.setdefault("paste_collapse_threshold", 0)
|
|
727
|
+
cfg.setdefault("paste_collapse_char_threshold", 0)
|
|
728
|
+
cfg.setdefault("context_file_max_chars", 200000)
|
|
729
|
+
|
|
730
|
+
new_txt = ("# Auto-generated oleh Sonnet Desktop — override user "
|
|
731
|
+
"ditulis ulang tiap respawn, JANGAN edit manual.\n"
|
|
732
|
+
"# Sumber template: hermes_config_template.yaml\n\n"
|
|
733
|
+
+ yaml.safe_dump(cfg, sort_keys=False,
|
|
734
|
+
default_flow_style=False,
|
|
735
|
+
allow_unicode=True))
|
|
736
|
+
# Self-check: dump dari dict SELALU syntactically valid, jadi
|
|
737
|
+
# ini jaring pengaman terakhir, bukan langkah yang "emang
|
|
738
|
+
# diharapkan gagal" — tapi kalau somehow tetep gagal, JANGAN
|
|
739
|
+
# nimpa config.yaml yang masih hidup dengan sesuatu yang
|
|
740
|
+
# mungkin lebih rusak.
|
|
741
|
+
yaml.safe_load(new_txt)
|
|
742
|
+
cfg_path.write_text(new_txt, encoding="utf-8")
|
|
743
|
+
except Exception as e:
|
|
744
|
+
print(f"BATAL update config.yaml — {e!r} (config.yaml LAMA "
|
|
745
|
+
f"dibiarin apa adanya, dicoba lagi turn berikutnya)",
|
|
746
|
+
flush=True)
|
|
747
|
+
|
|
748
|
+
# ── FIX (05 Sep): key internal Sonnet↔hermes gateway. TIDAK PERNAH
|
|
749
|
+
# diisi/dilihat user — di-generate sekali per-workdir pas pertama kali
|
|
750
|
+
# dibutuhkan, disimpen di 2 tempat: config.yaml (biar hermes gateway
|
|
751
|
+
# baca dari situ) + file lokal .hermes/.sonnet_gateway_key (biar
|
|
752
|
+
# gui_server.py bisa baca tanpa parse ulang YAML tiap request).
|
|
753
|
+
# Loopback-only (127.0.0.1) — key ini cuma jaga proses lain di mesin
|
|
754
|
+
# yang sama gak nebeng akses ke toolset hermes (terminal dll), BUKAN
|
|
755
|
+
# secret yang perlu di-treat kayak API key provider LLM.
|
|
756
|
+
def _ensure_api_server_key(self) -> str:
|
|
757
|
+
hdir = _hermes_home(self.workdir)
|
|
758
|
+
hdir.mkdir(parents=True, exist_ok=True)
|
|
759
|
+
key_path = hdir / ".sonnet_gateway_key"
|
|
760
|
+
if key_path.exists():
|
|
761
|
+
key = key_path.read_text(encoding="utf-8").strip()
|
|
762
|
+
if key:
|
|
763
|
+
self._sync_gateway_key_to_config(key)
|
|
764
|
+
return key
|
|
765
|
+
import secrets
|
|
766
|
+
key = secrets.token_urlsafe(32)
|
|
767
|
+
key_path.write_text(key, encoding="utf-8")
|
|
768
|
+
self._sync_gateway_key_to_config(key)
|
|
769
|
+
return key
|
|
770
|
+
|
|
771
|
+
def _sync_gateway_key_to_config(self, key: str):
|
|
772
|
+
"""Tulis key ke gateway.api_server.key di config.yaml (dipanggil
|
|
773
|
+
_ensure_hermes_config duluan biar section-nya udah ada dari
|
|
774
|
+
template — lihat hermes_config_template.yaml)."""
|
|
775
|
+
import re
|
|
776
|
+
cfg_path = _hermes_home(self.workdir) / "config.yaml"
|
|
777
|
+
try:
|
|
778
|
+
txt = cfg_path.read_text(encoding="utf-8")
|
|
779
|
+
except Exception:
|
|
780
|
+
return
|
|
781
|
+
if re.search(r"(?m)^(\s*)key:\s*\"[^\"]*\"\s*$", txt):
|
|
782
|
+
# replace key: "..." PALING BAWAH aja yg ada indentasi (di
|
|
783
|
+
# dalem gateway.api_server:) — cukup 1 baris cocok pola ini
|
|
784
|
+
# di file kita karena api_key model beda key ("api_key:").
|
|
785
|
+
txt = re.sub(r'(?m)^(\s*)key:\s*"[^"]*"\s*$',
|
|
786
|
+
lambda m: f'{m.group(1)}key: "{key}"', txt, count=1)
|
|
787
|
+
else:
|
|
788
|
+
txt += (f'\ngateway:\n api_server:\n enabled: true\n'
|
|
789
|
+
f' host: 127.0.0.1\n port: 8642\n key: "{key}"\n')
|
|
790
|
+
try:
|
|
791
|
+
cfg_path.write_text(txt, encoding="utf-8")
|
|
792
|
+
except Exception:
|
|
793
|
+
pass
|
|
794
|
+
|
|
795
|
+
def spawn_gateway(self, port: int = 8642):
|
|
796
|
+
"""Ganti _run_oneshot: nyalain `hermes gateway` SEKALI (persistent,
|
|
797
|
+
bukan spawn ulang tiap pesan). gui_server.py ngobrol ke proses ini
|
|
798
|
+
lewat HTTP+SSE (lihat hermes_gateway_client.py), bukan baca stdout-nya
|
|
799
|
+
langsung — jadi stdout proc ini gak perlu di-parse sama sekali."""
|
|
800
|
+
if self.proc is not None and self.proc.poll() is None:
|
|
801
|
+
return # udah jalan
|
|
802
|
+
self._ensure_hermes_config()
|
|
803
|
+
self._ensure_hermes_auth()
|
|
804
|
+
self._ensure_soul()
|
|
805
|
+
self._ensure_skills()
|
|
806
|
+
key = self._ensure_api_server_key()
|
|
807
|
+
env = os.environ.copy()
|
|
808
|
+
# FIX (11 Sep): tambahin folder cua + runtime/Scripts ke PATH biar
|
|
809
|
+
# hermes CLI bisa nemu cua-computer-server.exe
|
|
810
|
+
base = Path(__file__).resolve().parent.parent
|
|
811
|
+
cua_dir = str(base / "cua")
|
|
812
|
+
runtime_dir = str(base / "runtime")
|
|
813
|
+
runtime_scripts = str(base / "runtime" / "Scripts")
|
|
814
|
+
# FIX: tambahin juga path cua-driver yang di-install hermes
|
|
815
|
+
cua_driver_path = str(Path.home() / "AppData" / "Local" / "Programs" / "Cua" / "cua-driver" / "bin")
|
|
816
|
+
env["PATH"] = cua_dir + os.pathsep + runtime_dir + os.pathsep + runtime_scripts + os.pathsep + cua_driver_path + os.pathsep + env.get("PATH", "")
|
|
817
|
+
env.update({
|
|
818
|
+
# HOME ga di-override: Hermes hormat HERMES_HOME, dan
|
|
819
|
+
# memaksa HOME ke workdir bikin auth global user
|
|
820
|
+
# (~/.hermes/auth.json untuk Portal OAuth) gak ketemu —
|
|
821
|
+
# gejalanya oneshot diam tanpa error. Dulu HOME di-paksa
|
|
822
|
+
# karena .hermes masih di workdir/.hermes; sekarang
|
|
823
|
+
# HERMES_HOME yg dipisah dari workdir.
|
|
824
|
+
"HERMES_HOME": str(_hermes_home(self.workdir)),
|
|
825
|
+
"PYTHONUTF8": "1",
|
|
826
|
+
"API_SERVER_ENABLED": "true",
|
|
827
|
+
"API_SERVER_PORT": str(port),
|
|
828
|
+
"API_SERVER_HOST": "127.0.0.1",
|
|
829
|
+
"API_SERVER_KEY": key,
|
|
830
|
+
})
|
|
831
|
+
_prov = (getattr(self, "provider", "") or "").lower().strip() or "deepseek"
|
|
832
|
+
if _prov == "hermes":
|
|
833
|
+
_prov = "nous"
|
|
834
|
+
_key_env = _PROVIDER_KEY_ENV.get(_prov, f"{_prov.upper()}_API_KEY")
|
|
835
|
+
env[_key_env] = self.api_key
|
|
836
|
+
hermes = self._find_hermes()
|
|
837
|
+
cmd = [hermes, "gateway"]
|
|
838
|
+
if self.profile:
|
|
839
|
+
cmd[1:1] = ["-p", self.profile]
|
|
840
|
+
gw_log_path = _hermes_home(self.workdir) / "gateway.log"
|
|
841
|
+
gw_log_path.parent.mkdir(parents=True, exist_ok=True)
|
|
842
|
+
# FIX: dulu stdout/stderr proc ini di-DEVNULL total — kalau `hermes
|
|
843
|
+
# gateway` gagal start (config salah, port kepake, dependency
|
|
844
|
+
# ilang, dst) gak ada JEJAK APAPUN buat diagnosis, proc mati diem2
|
|
845
|
+
# & _ensure_gateway_ready() di gui_server.py cuma timeout generik
|
|
846
|
+
# ("hermes gateway gak ready dalam Ns"). Sekarang redirect ke
|
|
847
|
+
# gateway.log (append, biar histori beberapa kali respawn/crash
|
|
848
|
+
# kebaca, bukan ketimpa). File handle di PARENT aman ditutup abis
|
|
849
|
+
# Popen — child udah punya duplikat fd/handle sendiri (Windows
|
|
850
|
+
# maupun POSIX), sama pola kayak _logfile tmux di atas cuma lewat
|
|
851
|
+
# Popen langsung, bukan `tmux pipe-pane`.
|
|
852
|
+
gw_log = open(gw_log_path, "a", encoding="utf-8")
|
|
853
|
+
gw_log.write(f"\n=== spawn {time.strftime('%Y-%m-%d %H:%M:%S')} — {cmd!r} ===\n")
|
|
854
|
+
gw_log.flush()
|
|
855
|
+
self.proc = subprocess.Popen(
|
|
856
|
+
cmd, stdin=subprocess.DEVNULL,
|
|
857
|
+
stdout=gw_log, stderr=subprocess.STDOUT,
|
|
858
|
+
env=env, cwd=str(self.workdir))
|
|
859
|
+
gw_log.close()
|
|
860
|
+
self.gateway_key = key
|
|
861
|
+
self.gateway_port = port
|
|
862
|
+
self.gateway_log_path = gw_log_path
|
|
863
|
+
|
|
864
|
+
def _run_oneshot(self, text: str):
|
|
865
|
+
"""Windows: spawn `hermes chat -q <text> -Q` (non-interactive,
|
|
866
|
+
gak butuh TTY). Output stream → queue. session_id di-parse dari
|
|
867
|
+
output → dipake --resume buat konteks lanjut."""
|
|
868
|
+
import shlex
|
|
869
|
+
# FIX (31 Agu): generate/repair config.yaml SEBELUM spawn — kalau
|
|
870
|
+
# config kosong, hermes masuk gate "not configured" → nanya interaktif
|
|
871
|
+
# "Run setup now? [Y/n]" → stdin DEVNULL → HANG PERMANEN.
|
|
872
|
+
self._ensure_hermes_config()
|
|
873
|
+
self._ensure_hermes_auth() # FIX (04 Sep): sync token OAuth ke HERMES_HOME aktif
|
|
874
|
+
env = os.environ.copy()
|
|
875
|
+
# FIX (11 Sep): tambahin folder cua + runtime/Scripts ke PATH biar
|
|
876
|
+
# hermes CLI bisa nemu cua-computer-server.exe
|
|
877
|
+
base = Path(__file__).resolve().parent.parent
|
|
878
|
+
cua_dir = str(base / "cua")
|
|
879
|
+
runtime_dir = str(base / "runtime")
|
|
880
|
+
runtime_scripts = str(base / "runtime" / "Scripts")
|
|
881
|
+
# FIX: tambahin juga path cua-driver yang di-install hermes
|
|
882
|
+
cua_driver_path = str(Path.home() / "AppData" / "Local" / "Programs" / "Cua" / "cua-driver" / "bin")
|
|
883
|
+
env["PATH"] = cua_dir + os.pathsep + runtime_dir + os.pathsep + runtime_scripts + os.pathsep + cua_driver_path + os.pathsep + env.get("PATH", "")
|
|
884
|
+
env.update({
|
|
885
|
+
# HOME ga di-override: Hermes hormat HERMES_HOME, dan
|
|
886
|
+
# memaksa HOME ke workdir bikin auth global user
|
|
887
|
+
# (~/.hermes/auth.json untuk Portal OAuth) gak ketemu —
|
|
888
|
+
# gejalanya oneshot diam tanpa error. Dulu HOME di-paksa
|
|
889
|
+
# karena .hermes masih di workdir/.hermes; sekarang
|
|
890
|
+
# HERMES_HOME yg dipisah dari workdir.
|
|
891
|
+
"HERMES_HOME": str(_hermes_home(self.workdir)),
|
|
892
|
+
"TERMINAL_CWD": str(self.workdir),
|
|
893
|
+
"UB_MODEL": self.model,
|
|
894
|
+
"UB_API_KEY": self.api_key,
|
|
895
|
+
"PYTHONUTF8": "1",
|
|
896
|
+
"HERMES_DEFER_AGENT_STARTUP": "1",
|
|
897
|
+
# FIX (01 Sep): biar kerjaan panjang (CTF, exploit, riset) gak
|
|
898
|
+
# ke-potong di 12 iterasi — config max_turns 150 + env backup.
|
|
899
|
+
"HERMES_MAX_ITERATIONS": "150",
|
|
900
|
+
})
|
|
901
|
+
# FIX (02 Sep #12): UB_BASE_URL gak pernah di-set di jalur Windows
|
|
902
|
+
# ini sama sekali (padahal Linux path di spawn() udah nyetel) —
|
|
903
|
+
# config.yaml SUDAH bener nulis base_url per-provider (lihat
|
|
904
|
+
# _ensure_hermes_config), tapi kalau hermes CLI prioritasin env
|
|
905
|
+
# var di atas config file (umum di banyak CLI tool), base_url yang
|
|
906
|
+
# bener gak pernah nyampe ke proc-nya. Sekarang disamain: env ikut
|
|
907
|
+
# self.base_url (hasil resolve dari registry model aktif), bukan
|
|
908
|
+
# ke-tebak dari nama model kayak sebelumnya.
|
|
909
|
+
if getattr(self, "base_url", None):
|
|
910
|
+
env["UB_BASE_URL"] = self.base_url
|
|
911
|
+
# FIX (02 Sep #12 → #13): provider → env var mapping GENERIC, bukan
|
|
912
|
+
# hardcoded `DEEPSEEK_API_KEY` doang. Hermes CLI provider resolver
|
|
913
|
+
# cek env var per-prefix (OPENROUTER_API_KEY, GMI_API_KEY, dll —
|
|
914
|
+
# lihat cli-config.yaml.example) — kalau gak ada, dia bail
|
|
915
|
+
# ("Provider resolver returned an empty API key"). Sebelumnya
|
|
916
|
+
# cuma `DEEPSEEK_API_KEY` di-inject, jadi provider lain (GMI,
|
|
917
|
+
# OpenRouter, custom) gagal despite key udah di-set di UI
|
|
918
|
+
# (config.yaml bener, tapi env var ke provider-specific prefix
|
|
919
|
+
# gak pernah di-pass). Sekarang: provider_slug → key_env_var
|
|
920
|
+
# pake mapping, fallback ke `<PROVIDER>_API_KEY`. Result: user
|
|
921
|
+
# add provider bebas di settings UI → env var yg cocok ke-inject
|
|
922
|
+
# otomatis pas spawn, gak perlu patch ulang tiap provider baru.
|
|
923
|
+
_prov = (getattr(self, "provider", "") or "").lower().strip()
|
|
924
|
+
# FIX (03 Sep): provider "hermes" (UI slug) → "nous" (hermes CLI
|
|
925
|
+
# provider name). hermes CLI gak recognize "hermes" sebagai provider.
|
|
926
|
+
if _prov == "hermes":
|
|
927
|
+
_prov = "nous"
|
|
928
|
+
if not _prov:
|
|
929
|
+
# provider default/kosong → set DEEPSEEK_API_KEY (default lama)
|
|
930
|
+
env["DEEPSEEK_API_KEY"] = self.api_key
|
|
931
|
+
else:
|
|
932
|
+
_key_env = _PROVIDER_KEY_ENV.get(_prov, f"{_prov.upper()}_API_KEY")
|
|
933
|
+
env[_key_env] = self.api_key
|
|
934
|
+
if getattr(self, "thinking", None):
|
|
935
|
+
env["UB_REASONING_EFFORT"] = self.thinking
|
|
936
|
+
env["REASONING_EFFORT"] = self.thinking
|
|
937
|
+
if self.tavily_key:
|
|
938
|
+
env["TAVILY_API_KEY"] = self.tavily_key
|
|
939
|
+
hermes = self._find_hermes()
|
|
940
|
+
# FIX (02 Sep): JANGAN pake -Q (quiet) — hermes force
|
|
941
|
+
# tool_progress_mode="off" di quiet mode → tool preview ("┊ ✍️
|
|
942
|
+
# write ...", "┊ 📖 read ...") di-suppress TOTAL → pane Activity
|
|
943
|
+
# gak pernah ke-trigger (user kira agent gak pake tools). Tanpa -Q
|
|
944
|
+
# tool progress ke-render; noise tambahan (Query:, footer Session:)
|
|
945
|
+
# di-handle stream_filter + parser session_id (dua format).
|
|
946
|
+
cmd = [hermes, "chat", "-q", text, "--yolo", "--no-restore-cwd",
|
|
947
|
+
# FIX (02 Sep #4): -v (verbose) → hermes emit info context:
|
|
948
|
+
# stdout: "📊 Context limit: N tokens (compress at P% = M)"
|
|
949
|
+
# stderr: "Token usage: prompt=N, completion=M"
|
|
950
|
+
# (tanpa -v dua-duanya di-suppress di oneshot mode). Baris
|
|
951
|
+
# logging "HH:MM:SS - module - LEVEL" ikut ke-emit → di-drop
|
|
952
|
+
# stream_filter. Dipake gui_server buat ctx bar + deteksi
|
|
953
|
+
# auto-compact aktif.
|
|
954
|
+
"-v",
|
|
955
|
+
"-t", self._tools_flag()]
|
|
956
|
+
if self.profile:
|
|
957
|
+
prof_dir = _hermes_home(self.workdir) / "profiles" / self.profile
|
|
958
|
+
if prof_dir.exists():
|
|
959
|
+
cmd[1:1] = ["-p", self.profile]
|
|
960
|
+
if getattr(self, "session_id", None):
|
|
961
|
+
cmd += ["--resume", self.session_id]
|
|
962
|
+
print("oneshot: " + " ".join(cmd[:6]) + "...", flush=True)
|
|
963
|
+
# FIX (04 Sep #2): tutup PAKSA proc + reader thread LAMA (kalau
|
|
964
|
+
# masih ada/nyangkut — mis. warmup probe yang timeout 90s tanpa
|
|
965
|
+
# sempet early-exit, atau chat sebelumnya yang di-stop tapi
|
|
966
|
+
# procnya belum bener2 kelar exit) SEBELUM self.proc di-assign
|
|
967
|
+
# ke proc BARU di bawah. Kenapa ini WAJIB: _reader() baca
|
|
968
|
+
# `self.proc.stdout` ULANG tiap iterasi loop (bukan snapshot
|
|
969
|
+
# sekali di awal) — kalau thread reader lama masih hidup pas
|
|
970
|
+
# self.proc ketiban proc baru, thread lama itu bakal nyasar ikut
|
|
971
|
+
# baca stdout proc BARU di iterasi berikutnya. Dua thread rebutan
|
|
972
|
+
# baca 1 pipe yang sama = baris ke-korup/ke-drop/ke-duplikat, dan
|
|
973
|
+
# readline() concurrent kayak gini kadang raise exception yang
|
|
974
|
+
# bikin salah satu thread MATI DIAM-DIAM (gak ada try/except di
|
|
975
|
+
# _reader) → poll_output() selamanya kosong → chat kayak gak
|
|
976
|
+
# keproses sampe STUCK 5 menit baru ketauan. Ini persis gejala:
|
|
977
|
+
# "abis idle lama/baru buka app, chat pertama gak ke-proses,
|
|
978
|
+
# harus stop+kirim ulang baru jalan" — warmup probe yang lambat
|
|
979
|
+
# nyerempet chat pertama beneran, exact race di atas.
|
|
980
|
+
_old_proc, _old_thread = self.proc, self._thread
|
|
981
|
+
if _old_proc is not None:
|
|
982
|
+
try:
|
|
983
|
+
if _old_proc.poll() is None:
|
|
984
|
+
_old_proc.terminate()
|
|
985
|
+
except Exception:
|
|
986
|
+
pass
|
|
987
|
+
if _old_thread is not None and _old_thread.is_alive():
|
|
988
|
+
_old_thread.join(timeout=2.0)
|
|
989
|
+
if _old_thread.is_alive():
|
|
990
|
+
# 2s gak cukup (proc bandel nolak terminate) — paksa kill
|
|
991
|
+
try:
|
|
992
|
+
if _old_proc is not None and _old_proc.poll() is None:
|
|
993
|
+
_old_proc.kill()
|
|
994
|
+
except Exception:
|
|
995
|
+
pass
|
|
996
|
+
_old_thread.join(timeout=2.0)
|
|
997
|
+
if _old_thread.is_alive():
|
|
998
|
+
print("WARNING: reader thread lama gak mau berhenti "
|
|
999
|
+
"dalam 4s — lanjut spawn proc baru, tapi race "
|
|
1000
|
+
"masih mungkin kejadian sekali ini", flush=True)
|
|
1001
|
+
self.proc = subprocess.Popen(
|
|
1002
|
+
cmd, stdin=subprocess.DEVNULL,
|
|
1003
|
+
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
|
|
1004
|
+
text=True, encoding="utf-8", errors="replace",
|
|
1005
|
+
env=env, cwd=str(self.workdir), bufsize=1)
|
|
1006
|
+
self._thread = threading.Thread(target=self._reader, daemon=True)
|
|
1007
|
+
self._thread.start()
|
|
1008
|
+
|
|
1009
|
+
def _reader(self):
|
|
1010
|
+
assert self.proc and self.proc.stdout
|
|
1011
|
+
while True:
|
|
1012
|
+
line = self.proc.stdout.readline()
|
|
1013
|
+
if not line:
|
|
1014
|
+
break
|
|
1015
|
+
self._out_queue.put(line)
|
|
1016
|
+
|
|
1017
|
+
def _reader_pty(self):
|
|
1018
|
+
"""Baca dari pty master → queue (chunk-based, pty gak ada readline)."""
|
|
1019
|
+
import os as _os
|
|
1020
|
+
while True:
|
|
1021
|
+
try:
|
|
1022
|
+
data = _os.read(self._pty_master, 4096)
|
|
1023
|
+
if not data:
|
|
1024
|
+
break
|
|
1025
|
+
self._out_queue.put(data.decode("utf-8", errors="replace"))
|
|
1026
|
+
except Exception:
|
|
1027
|
+
break
|
|
1028
|
+
|
|
1029
|
+
def is_alive(self) -> bool:
|
|
1030
|
+
"""Cek hermes process masih hidup (winpty/tmux/pipe/oneshot).
|
|
1031
|
+
FIX (31 Agu) oneshot: proc udah exit TAPI session_id masih ada =
|
|
1032
|
+
konteks bisa di-resume via --resume — jangan dianggap mati, kalau
|
|
1033
|
+
mati ensure_session bakal respawn & session_id hilang → konteks
|
|
1034
|
+
antar-chat ilang (agent lupa chat sebelumnya)."""
|
|
1035
|
+
try:
|
|
1036
|
+
if getattr(self, "_oneshot", False):
|
|
1037
|
+
if self.proc and self.proc.poll() is None:
|
|
1038
|
+
return True
|
|
1039
|
+
# proc exit — masih "hidup" kalo punya session_id buat resume
|
|
1040
|
+
return bool(getattr(self, "session_id", None))
|
|
1041
|
+
if hasattr(self, "_tmux_name"):
|
|
1042
|
+
r = subprocess.run(["tmux", "has-session", "-t",
|
|
1043
|
+
self._tmux_name], capture_output=True)
|
|
1044
|
+
return r.returncode == 0
|
|
1045
|
+
if getattr(self, "_winpty", None):
|
|
1046
|
+
return bool(self._winpty.isalive())
|
|
1047
|
+
if self.proc:
|
|
1048
|
+
return self.proc.poll() is None
|
|
1049
|
+
except Exception:
|
|
1050
|
+
pass
|
|
1051
|
+
return False
|
|
1052
|
+
|
|
1053
|
+
def send(self, text: str):
|
|
1054
|
+
if getattr(self, "_oneshot", False):
|
|
1055
|
+
self._run_oneshot(text)
|
|
1056
|
+
return
|
|
1057
|
+
if hasattr(self, "_tmux_name"):
|
|
1058
|
+
# ── submit robust: tmux send-keys flaky (Enter ke-drop pas
|
|
1059
|
+
# render). teks dikirim literal, terus Enter diulang tiap
|
|
1060
|
+
# 1.5s SAMPE teks ilang dari prompt (capture-pane) — baru
|
|
1061
|
+
# dianggap ke-submit. gak peduli timing render. ──
|
|
1062
|
+
import re as _re
|
|
1063
|
+
subprocess.run(["tmux", "send-keys", "-t", self._tmux_name,
|
|
1064
|
+
"-l", text], check=False)
|
|
1065
|
+
for _ in range(10):
|
|
1066
|
+
time.sleep(1.5)
|
|
1067
|
+
try:
|
|
1068
|
+
r = subprocess.run(
|
|
1069
|
+
["tmux", "capture-pane", "-p", "-t", self._tmux_name],
|
|
1070
|
+
capture_output=True, text=True, timeout=5)
|
|
1071
|
+
pane = _re.sub(r"\x1b\[[0-9;? ]*[A-Za-z]", "", r.stdout or "")
|
|
1072
|
+
except Exception:
|
|
1073
|
+
pane = ""
|
|
1074
|
+
# teks masih di prompt "❯ <teks>" → belum submit → Enter lagi
|
|
1075
|
+
if f"❯ {text}" in pane or f"> {text}" in pane:
|
|
1076
|
+
subprocess.run(["tmux", "send-keys", "-t",
|
|
1077
|
+
self._tmux_name, "Enter"], check=False)
|
|
1078
|
+
continue
|
|
1079
|
+
# teks udah ilang dari prompt = ke-submit (atau prompt
|
|
1080
|
+
# ke-render ulang) — pastikan prompt kosong sebelum exit
|
|
1081
|
+
if "❯" in pane:
|
|
1082
|
+
return
|
|
1083
|
+
# timeout 15s: kirim Enter sekali terakhir buat jaga-jaga
|
|
1084
|
+
subprocess.run(["tmux", "send-keys", "-t", self._tmux_name,
|
|
1085
|
+
"Enter"], check=False)
|
|
1086
|
+
elif os.name == "posix" and hasattr(self, "_pty_master"):
|
|
1087
|
+
os.write(self._pty_master, (text + "\r").encode("utf-8"))
|
|
1088
|
+
elif getattr(self, "_winpty", None):
|
|
1089
|
+
# ── winpty ConPTY flaky kayak tmux: Enter bisa ke-drop pas
|
|
1090
|
+
# render. pisahin teks & Enter + retry kalau gak ada
|
|
1091
|
+
# output sama sekali (gak ke-submit). ──
|
|
1092
|
+
self._winpty.write(text)
|
|
1093
|
+
time.sleep(0.3)
|
|
1094
|
+
self._winpty.write("\r")
|
|
1095
|
+
for _ in range(3):
|
|
1096
|
+
time.sleep(1.5)
|
|
1097
|
+
if not self._out_queue.empty():
|
|
1098
|
+
return # ada output = ke-submit
|
|
1099
|
+
self._winpty.write("\r")
|
|
1100
|
+
else:
|
|
1101
|
+
assert self.proc and self.proc.stdin
|
|
1102
|
+
self.proc.stdin.write(text + "\n")
|
|
1103
|
+
self.proc.stdin.flush()
|
|
1104
|
+
|
|
1105
|
+
def stop(self):
|
|
1106
|
+
"""Stop generation yang lagi jalan (interrupt hermes).
|
|
1107
|
+
Dipanggil dari websocket {type: 'stop'} (tombol '■ hentikan')."""
|
|
1108
|
+
try:
|
|
1109
|
+
if hasattr(self, "_tmux_name"):
|
|
1110
|
+
subprocess.run(["tmux", "send-keys", "-t", self._tmux_name,
|
|
1111
|
+
"C-c"], check=False)
|
|
1112
|
+
elif os.name == "posix" and hasattr(self, "_pty_master"):
|
|
1113
|
+
os.write(self._pty_master, b"\x03")
|
|
1114
|
+
elif getattr(self, "_winpty", None):
|
|
1115
|
+
self._winpty.write("\x03")
|
|
1116
|
+
elif self.proc and self.proc.poll() is None:
|
|
1117
|
+
self.proc.terminate()
|
|
1118
|
+
except Exception:
|
|
1119
|
+
pass
|
|
1120
|
+
|
|
1121
|
+
def wait_ready(self, timeout: float = 60) -> bool:
|
|
1122
|
+
"""Tunggu hermes siap (prompt '>' muncul di output) — kayak userbot probe.
|
|
1123
|
+
Return True kalau udah siap, False kalau timeout."""
|
|
1124
|
+
t0 = time.time()
|
|
1125
|
+
buf = ""
|
|
1126
|
+
while time.time() - t0 < timeout:
|
|
1127
|
+
for line in self.poll_output(0.3):
|
|
1128
|
+
buf += line
|
|
1129
|
+
if "❯" in buf or "> " in buf:
|
|
1130
|
+
return True
|
|
1131
|
+
time.sleep(0.2)
|
|
1132
|
+
return False
|
|
1133
|
+
|
|
1134
|
+
def poll_output(self, timeout: float = 0.1):
|
|
1135
|
+
"""Ambil semua output yang udah masuk (non-blocking)."""
|
|
1136
|
+
lines = []
|
|
1137
|
+
try:
|
|
1138
|
+
while True:
|
|
1139
|
+
lines.append(self._out_queue.get(timeout=timeout))
|
|
1140
|
+
except queue.Empty:
|
|
1141
|
+
pass
|
|
1142
|
+
return lines
|
|
1143
|
+
|
|
1144
|
+
def close(self):
|
|
1145
|
+
if getattr(self, "_oneshot", False):
|
|
1146
|
+
if self.proc:
|
|
1147
|
+
try:
|
|
1148
|
+
self.proc.kill()
|
|
1149
|
+
except Exception:
|
|
1150
|
+
pass
|
|
1151
|
+
self.proc = None
|
|
1152
|
+
return
|
|
1153
|
+
if hasattr(self, "_tmux_name"):
|
|
1154
|
+
subprocess.run(["tmux", "kill-session", "-t", self._tmux_name],
|
|
1155
|
+
capture_output=True, check=False)
|
|
1156
|
+
try:
|
|
1157
|
+
os.unlink(self._logfile) # bersihin logfile stream
|
|
1158
|
+
except Exception:
|
|
1159
|
+
pass
|
|
1160
|
+
if os.name == "posix" and hasattr(self, "_pty_master"):
|
|
1161
|
+
try:
|
|
1162
|
+
os.close(self._pty_master)
|
|
1163
|
+
except Exception:
|
|
1164
|
+
pass
|
|
1165
|
+
if self.proc:
|
|
1166
|
+
try:
|
|
1167
|
+
self.proc.terminate()
|
|
1168
|
+
except Exception:
|
|
1169
|
+
pass
|
|
1170
|
+
self.proc = None
|
|
1171
|
+
if getattr(self, "_winpty", None):
|
|
1172
|
+
try:
|
|
1173
|
+
self._winpty.terminate()
|
|
1174
|
+
except Exception:
|
|
1175
|
+
pass
|
|
1176
|
+
self._winpty = None
|
|
1177
|
+
|
|
1178
|
+
|
|
1179
|
+
if __name__ == "__main__":
|
|
1180
|
+
# smoke test: spawn hermes, kirim halo, baca output 15 detik
|
|
1181
|
+
key = os.environ.get("DEEPSEEK_API_KEY", "")
|
|
1182
|
+
if not key:
|
|
1183
|
+
print("set DEEPSEEK_API_KEY dulu")
|
|
1184
|
+
raise SystemExit(1)
|
|
1185
|
+
s = HermesSession(key)
|
|
1186
|
+
s.spawn()
|
|
1187
|
+
import time
|
|
1188
|
+
time.sleep(8) # pre-warm
|
|
1189
|
+
s.send("halo, balas singkat")
|
|
1190
|
+
t0 = time.time()
|
|
1191
|
+
while time.time() - t0 < 15:
|
|
1192
|
+
for line in s.poll_output():
|
|
1193
|
+
print(line, end="")
|
|
1194
|
+
time.sleep(0.3)
|
|
1195
|
+
s.close()
|