Skip to content

Commit b2e265e

Browse files
committed
Complete HackCode engine — branding, scanner, setup wizard, uncensored model support
- Rename all .claw/ → .hackcode/, CLAW_CONFIG_HOME → HACKCODE_CONFIG_HOME across 20+ files - Add security tool scanner (35 tools across 6 categories, --scan flag) - Add first-run setup wizard with auto Ollama install, model selection, brew tools - Update model list to working Qwen3.5 uncensored models (tripolskypetr, vaultbox) - Setup auto-creates hackcode-uncensored with native Qwen3.5 renderer/parser - Add auto-start for Ollama + config system (~/.config/hackcode/config.json) - Add hackcode-mode system prompt — action-first, tool-chaining, thorough exploration - Strip <think> tags from Qwen thinking models in streaming output - Filter SendUserMessage/Brief/Config tools that confuse local models - Add hackcode/qwen model detection in Ollama provider routing - Include Modelfile with Qwen3.5 native renderer and stop tokens
1 parent 276e1e3 commit b2e265e

25 files changed

Lines changed: 897 additions & 326 deletions

File tree

Modelfile

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
FROM tripolskypetr/qwen3.5-uncensored-aggressive:35b
2+
3+
RENDERER qwen3.5
4+
PARSER qwen3.5
5+
6+
PARAMETER stop "<|im_start|>"
7+
PARAMETER stop "<|im_end|>"
8+
PARAMETER stop "<|endoftext|>"
9+
PARAMETER temperature 0.7
10+
PARAMETER num_ctx 32768
11+
PARAMETER presence_penalty 1.5
12+
PARAMETER top_k 20
13+
PARAMETER top_p 0.95

rust/crates/api/src/providers/mod.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,11 @@ pub fn metadata_for_model(model: &str) -> Option<ProviderMetadata> {
198198
// Ollama local models — HuggingFace models pulled via `ollama pull hf.co/...`
199199
// and any model containing a colon (e.g. "llama3.2:1b", "gemma:7b")
200200
if canonical.starts_with("hf.co/")
201+
|| canonical.starts_with("hackcode")
201202
|| canonical.contains(':')
202203
|| canonical.starts_with("llama")
203204
|| canonical.starts_with("gemma")
205+
|| canonical.starts_with("qwen")
204206
|| canonical.starts_with("mistral")
205207
|| canonical.starts_with("phi")
206208
|| canonical.starts_with("codellama")
@@ -531,7 +533,7 @@ mod tests {
531533

532534
#[test]
533535
fn qwen_prefix_routes_to_dashscope_not_anthropic() {
534-
// User request from Discord #clawcode-get-help: web3g wants to use
536+
// User request from Discord #hackcode-get-help: web3g wants to use
535537
// Qwen 3.6 Plus via native Alibaba DashScope API (not OpenRouter,
536538
// which has lower rate limits). metadata_for_model must route
537539
// qwen/* and bare qwen-* to the OpenAi provider kind pointed at
@@ -574,8 +576,8 @@ mod tests {
574576
.as_nanos();
575577
let root = std::env::temp_dir().join(format!("api-plugin-max-tokens-{nanos}"));
576578
let cwd = root.join("project");
577-
let home = root.join("home").join(".claw");
578-
std::fs::create_dir_all(cwd.join(".claw")).expect("project config dir");
579+
let home = root.join("home").join(".hackcode");
580+
std::fs::create_dir_all(cwd.join(".hackcode")).expect("project config dir");
579581
std::fs::create_dir_all(&home).expect("home config dir");
580582
std::fs::write(
581583
home.join("settings.json"),

rust/crates/api/src/providers/openai_compat.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ impl OpenAiCompatConfig {
6262

6363
/// Alibaba DashScope compatible-mode endpoint (Qwen family models).
6464
/// Uses the OpenAI-compatible REST shape at /compatible-mode/v1.
65-
/// Requested via Discord #clawcode-get-help: native Alibaba API for
65+
/// Requested via Discord #hackcode-get-help: native Alibaba API for
6666
/// higher rate limits than going through OpenRouter.
6767
#[must_use]
6868
pub const fn dashscope() -> Self {

rust/crates/api/tests/client_integration.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ async fn send_message_applies_request_profile_and_records_telemetry() {
169169
.with_base_url(server.base_url())
170170
.with_client_identity(ClientIdentity::new("claude-code", "9.9.9").with_runtime("rust-cli"))
171171
.with_beta("tools-2026-04-01")
172-
.with_extra_body_param("metadata", json!({"source": "clawd-code"}))
172+
.with_extra_body_param("metadata", json!({"source": "hackcode"}))
173173
.with_session_tracer(SessionTracer::new("session-telemetry", sink.clone()));
174174

175175
let response = client
@@ -191,7 +191,7 @@ async fn send_message_applies_request_profile_and_records_telemetry() {
191191
);
192192
let body: serde_json::Value =
193193
serde_json::from_str(&request.body).expect("request body should be json");
194-
assert_eq!(body["metadata"]["source"], json!("clawd-code"));
194+
assert_eq!(body["metadata"]["source"], json!("hackcode"));
195195
assert!(
196196
body.get("betas").is_none(),
197197
"betas must travel via the anthropic-beta header, not the request body"

rust/crates/commands/src/lib.rs

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ const SLASH_COMMAND_SPECS: &[SlashCommandSpec] = &[
230230
SlashCommandSpec {
231231
name: "plugin",
232232
aliases: &["plugins", "marketplace"],
233-
summary: "Manage Claw Code plugins",
233+
summary: "Manage HackCode plugins",
234234
argument_hint: Some(
235235
"[list|install <path>|enable <name>|disable <name>|uninstall <id>|update <id>]",
236236
),
@@ -2626,7 +2626,7 @@ fn discover_definition_roots(cwd: &Path, leaf: &str) -> Vec<(DefinitionSource, P
26262626
push_unique_root(
26272627
&mut roots,
26282628
DefinitionSource::ProjectClaw,
2629-
ancestor.join(".claw").join(leaf),
2629+
ancestor.join(".hackcode").join(leaf),
26302630
);
26312631
push_unique_root(
26322632
&mut roots,
@@ -2640,7 +2640,7 @@ fn discover_definition_roots(cwd: &Path, leaf: &str) -> Vec<(DefinitionSource, P
26402640
);
26412641
}
26422642

2643-
if let Ok(claw_config_home) = env::var("CLAW_CONFIG_HOME") {
2643+
if let Ok(claw_config_home) = env::var("HACKCODE_CONFIG_HOME") {
26442644
push_unique_root(
26452645
&mut roots,
26462646
DefinitionSource::UserClawConfigHome,
@@ -2669,7 +2669,7 @@ fn discover_definition_roots(cwd: &Path, leaf: &str) -> Vec<(DefinitionSource, P
26692669
push_unique_root(
26702670
&mut roots,
26712671
DefinitionSource::UserClaw,
2672-
home.join(".claw").join(leaf),
2672+
home.join(".hackcode").join(leaf),
26732673
);
26742674
push_unique_root(
26752675
&mut roots,
@@ -2694,7 +2694,7 @@ fn discover_skill_roots(cwd: &Path) -> Vec<SkillRoot> {
26942694
push_unique_skill_root(
26952695
&mut roots,
26962696
DefinitionSource::ProjectClaw,
2697-
ancestor.join(".claw").join("skills"),
2697+
ancestor.join(".hackcode").join("skills"),
26982698
SkillOrigin::SkillsDir,
26992699
);
27002700
push_unique_skill_root(
@@ -2724,7 +2724,7 @@ fn discover_skill_roots(cwd: &Path) -> Vec<SkillRoot> {
27242724
push_unique_skill_root(
27252725
&mut roots,
27262726
DefinitionSource::ProjectClaw,
2727-
ancestor.join(".claw").join("commands"),
2727+
ancestor.join(".hackcode").join("commands"),
27282728
SkillOrigin::LegacyCommandsDir,
27292729
);
27302730
push_unique_skill_root(
@@ -2741,7 +2741,7 @@ fn discover_skill_roots(cwd: &Path) -> Vec<SkillRoot> {
27412741
);
27422742
}
27432743

2744-
if let Ok(claw_config_home) = env::var("CLAW_CONFIG_HOME") {
2744+
if let Ok(claw_config_home) = env::var("HACKCODE_CONFIG_HOME") {
27452745
let claw_config_home = PathBuf::from(claw_config_home);
27462746
push_unique_skill_root(
27472747
&mut roots,
@@ -2778,7 +2778,7 @@ fn discover_skill_roots(cwd: &Path) -> Vec<SkillRoot> {
27782778
push_unique_skill_root(
27792779
&mut roots,
27802780
DefinitionSource::UserClaw,
2781-
home.join(".claw").join("skills"),
2781+
home.join(".hackcode").join("skills"),
27822782
SkillOrigin::SkillsDir,
27832783
);
27842784
push_unique_skill_root(
@@ -2790,7 +2790,7 @@ fn discover_skill_roots(cwd: &Path) -> Vec<SkillRoot> {
27902790
push_unique_skill_root(
27912791
&mut roots,
27922792
DefinitionSource::UserClaw,
2793-
home.join(".claw").join("commands"),
2793+
home.join(".hackcode").join("commands"),
27942794
SkillOrigin::LegacyCommandsDir,
27952795
);
27962796
push_unique_skill_root(
@@ -2902,18 +2902,18 @@ fn install_skill_into(
29022902
}
29032903

29042904
fn default_skill_install_root() -> std::io::Result<PathBuf> {
2905-
if let Ok(claw_config_home) = env::var("CLAW_CONFIG_HOME") {
2905+
if let Ok(claw_config_home) = env::var("HACKCODE_CONFIG_HOME") {
29062906
return Ok(PathBuf::from(claw_config_home).join("skills"));
29072907
}
29082908
if let Ok(codex_home) = env::var("CODEX_HOME") {
29092909
return Ok(PathBuf::from(codex_home).join("skills"));
29102910
}
29112911
if let Some(home) = env::var_os("HOME") {
2912-
return Ok(PathBuf::from(home).join(".claw").join("skills"));
2912+
return Ok(PathBuf::from(home).join(".hackcode").join("skills"));
29132913
}
29142914
Err(std::io::Error::new(
29152915
std::io::ErrorKind::NotFound,
2916-
"unable to resolve a skills install root; set CLAW_CONFIG_HOME or HOME",
2916+
"unable to resolve a skills install root; set HACKCODE_CONFIG_HOME or HOME",
29172917
))
29182918
}
29192919

@@ -3605,7 +3605,7 @@ fn render_agents_usage(unexpected: Option<&str>) -> String {
36053605
"Agents".to_string(),
36063606
" Usage /agents [list|help]".to_string(),
36073607
" Direct CLI claw agents".to_string(),
3608-
" Sources .claw/agents, ~/.claw/agents, $CLAW_CONFIG_HOME/agents".to_string(),
3608+
" Sources .hackcode/agents, ~/.hackcode/agents, $HACKCODE_CONFIG_HOME/agents".to_string(),
36093609
];
36103610
if let Some(args) = unexpected {
36113611
lines.push(format!(" Unexpected {args}"));
@@ -3620,7 +3620,7 @@ fn render_agents_usage_json(unexpected: Option<&str>) -> Value {
36203620
"usage": {
36213621
"slash_command": "/agents [list|help]",
36223622
"direct_cli": "claw agents [list|help]",
3623-
"sources": [".claw/agents", "~/.claw/agents", "$CLAW_CONFIG_HOME/agents"],
3623+
"sources": [".hackcode/agents", "~/.hackcode/agents", "$HACKCODE_CONFIG_HOME/agents"],
36243624
},
36253625
"unexpected": unexpected,
36263626
})
@@ -3633,8 +3633,8 @@ fn render_skills_usage(unexpected: Option<&str>) -> String {
36333633
" Alias /skill".to_string(),
36343634
" Direct CLI claw skills [list|install <path>|help|<skill> [args]]".to_string(),
36353635
" Invoke /skills help overview -> $help overview".to_string(),
3636-
" Install root $CLAW_CONFIG_HOME/skills or ~/.claw/skills".to_string(),
3637-
" Sources .claw/skills, .omc/skills, .agents/skills, .codex/skills, .claude/skills, ~/.claw/skills, ~/.omc/skills, ~/.claude/skills/omc-learned, ~/.codex/skills, ~/.claude/skills, legacy /commands".to_string(),
3636+
" Install root $HACKCODE_CONFIG_HOME/skills or ~/.hackcode/skills".to_string(),
3637+
" Sources .hackcode/skills, .omc/skills, .agents/skills, .codex/skills, .claude/skills, ~/.hackcode/skills, ~/.omc/skills, ~/.claude/skills/omc-learned, ~/.codex/skills, ~/.claude/skills, legacy /commands".to_string(),
36383638
];
36393639
if let Some(args) = unexpected {
36403640
lines.push(format!(" Unexpected {args}"));
@@ -3651,14 +3651,14 @@ fn render_skills_usage_json(unexpected: Option<&str>) -> Value {
36513651
"aliases": ["/skill"],
36523652
"direct_cli": "claw skills [list|install <path>|help|<skill> [args]]",
36533653
"invoke": "/skills help overview -> $help overview",
3654-
"install_root": "$CLAW_CONFIG_HOME/skills or ~/.claw/skills",
3654+
"install_root": "$HACKCODE_CONFIG_HOME/skills or ~/.hackcode/skills",
36553655
"sources": [
3656-
".claw/skills",
3656+
".hackcode/skills",
36573657
".omc/skills",
36583658
".agents/skills",
36593659
".codex/skills",
36603660
".claude/skills",
3661-
"~/.claw/skills",
3661+
"~/.hackcode/skills",
36623662
"~/.omc/skills",
36633663
"~/.claude/skills/omc-learned",
36643664
"~/.codex/skills",
@@ -3676,7 +3676,7 @@ fn render_mcp_usage(unexpected: Option<&str>) -> String {
36763676
"MCP".to_string(),
36773677
" Usage /mcp [list|show <server>|help]".to_string(),
36783678
" Direct CLI claw mcp [list|show <server>|help]".to_string(),
3679-
" Sources .claw/settings.json, .claw/settings.local.json".to_string(),
3679+
" Sources .hackcode/settings.json, .hackcode/settings.local.json".to_string(),
36803680
];
36813681
if let Some(args) = unexpected {
36823682
lines.push(format!(" Unexpected {args}"));
@@ -3691,7 +3691,7 @@ fn render_mcp_usage_json(unexpected: Option<&str>) -> Value {
36913691
"usage": {
36923692
"slash_command": "/mcp [list|show <server>|help]",
36933693
"direct_cli": "claw mcp [list|show <server>|help]",
3694-
"sources": [".claw/settings.json", ".claw/settings.local.json"],
3694+
"sources": [".hackcode/settings.json", ".hackcode/settings.local.json"],
36953695
},
36963696
"unexpected": unexpected,
36973697
})
@@ -4575,7 +4575,7 @@ mod tests {
45754575

45764576
// then
45774577
assert!(help.contains("/plugin"));
4578-
assert!(help.contains("Summary Manage Claw Code plugins"));
4578+
assert!(help.contains("Summary Manage HackCode plugins"));
45794579
assert!(help.contains("Aliases /plugins, /marketplace"));
45804580
assert!(help.contains("Category Tools"));
45814581
}
@@ -4928,8 +4928,8 @@ mod tests {
49284928
#[test]
49294929
fn resolves_project_skills_and_legacy_commands_from_shared_registry() {
49304930
let workspace = temp_dir("resolve-project-skills");
4931-
let project_skills = workspace.join(".claw").join("skills");
4932-
let legacy_commands = workspace.join(".claw").join("commands");
4931+
let project_skills = workspace.join(".hackcode").join("skills");
4932+
let legacy_commands = workspace.join(".hackcode").join("commands");
49334933

49344934
write_skill(&project_skills, "plan", "Project planning guidance");
49354935
write_legacy_command(&legacy_commands, "handoff", "Legacy handoff guidance");
@@ -5009,7 +5009,7 @@ mod tests {
50095009
assert!(agents_help.contains("Usage /agents [list|help]"));
50105010
assert!(agents_help.contains("Direct CLI claw agents"));
50115011
assert!(agents_help
5012-
.contains("Sources .claw/agents, ~/.claw/agents, $CLAW_CONFIG_HOME/agents"));
5012+
.contains("Sources .hackcode/agents, ~/.hackcode/agents, $HACKCODE_CONFIG_HOME/agents"));
50135013

50145014
let agents_unexpected =
50155015
super::handle_agents_slash_command(Some("show planner"), &cwd).expect("agents usage");
@@ -5021,7 +5021,7 @@ mod tests {
50215021
.contains("Usage /skills [list|install <path>|help|<skill> [args]]"));
50225022
assert!(skills_help.contains("Alias /skill"));
50235023
assert!(skills_help.contains("Invoke /skills help overview -> $help overview"));
5024-
assert!(skills_help.contains("Install root $CLAW_CONFIG_HOME/skills or ~/.claw/skills"));
5024+
assert!(skills_help.contains("Install root $HACKCODE_CONFIG_HOME/skills or ~/.hackcode/skills"));
50255025
assert!(skills_help.contains(".omc/skills"));
50265026
assert!(skills_help.contains(".agents/skills"));
50275027
assert!(skills_help.contains("~/.claude/skills/omc-learned"));
@@ -5154,10 +5154,10 @@ mod tests {
51545154
fn renders_mcp_reports_from_loaded_config() {
51555155
let workspace = temp_dir("mcp-config-workspace");
51565156
let config_home = temp_dir("mcp-config-home");
5157-
fs::create_dir_all(workspace.join(".claw")).expect("workspace config dir");
5157+
fs::create_dir_all(workspace.join(".hackcode")).expect("workspace config dir");
51585158
fs::create_dir_all(&config_home).expect("config home");
51595159
fs::write(
5160-
workspace.join(".claw").join("settings.json"),
5160+
workspace.join(".hackcode").join("settings.json"),
51615161
r#"{
51625162
"mcpServers": {
51635163
"alpha": {
@@ -5181,7 +5181,7 @@ mod tests {
51815181
)
51825182
.expect("write settings");
51835183
fs::write(
5184-
workspace.join(".claw").join("settings.local.json"),
5184+
workspace.join(".hackcode").join("settings.local.json"),
51855185
r#"{
51865186
"mcpServers": {
51875187
"remote": {
@@ -5231,10 +5231,10 @@ mod tests {
52315231
fn renders_mcp_reports_as_json() {
52325232
let workspace = temp_dir("mcp-json-workspace");
52335233
let config_home = temp_dir("mcp-json-home");
5234-
fs::create_dir_all(workspace.join(".claw")).expect("workspace config dir");
5234+
fs::create_dir_all(workspace.join(".hackcode")).expect("workspace config dir");
52355235
fs::create_dir_all(&config_home).expect("config home");
52365236
fs::write(
5237-
workspace.join(".claw").join("settings.json"),
5237+
workspace.join(".hackcode").join("settings.json"),
52385238
r#"{
52395239
"mcpServers": {
52405240
"alpha": {
@@ -5258,7 +5258,7 @@ mod tests {
52585258
)
52595259
.expect("write settings");
52605260
fs::write(
5261-
workspace.join(".claw").join("settings.local.json"),
5261+
workspace.join(".hackcode").join("settings.local.json"),
52625262
r#"{
52635263
"mcpServers": {
52645264
"remote": {
@@ -5303,7 +5303,7 @@ mod tests {
53035303
let help =
53045304
render_mcp_report_json_for(&loader, &workspace, Some("help")).expect("mcp help json");
53055305
assert_eq!(help["action"], "help");
5306-
assert_eq!(help["usage"]["sources"][0], ".claw/settings.json");
5306+
assert_eq!(help["usage"]["sources"][0], ".hackcode/settings.json");
53075307

53085308
let _ = fs::remove_dir_all(workspace);
53095309
let _ = fs::remove_dir_all(config_home);

rust/crates/compat-harness/src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,12 @@ fn upstream_repo_candidates(primary_repo_root: &Path) -> Vec<PathBuf> {
7070
}
7171

7272
for ancestor in primary_repo_root.ancestors().take(4) {
73-
candidates.push(ancestor.join("claw-code"));
74-
candidates.push(ancestor.join("clawd-code"));
73+
candidates.push(ancestor.join("hackcode"));
74+
candidates.push(ancestor.join("hackcode"));
7575
}
7676

77-
candidates.push(primary_repo_root.join("reference-source").join("claw-code"));
78-
candidates.push(primary_repo_root.join("vendor").join("claw-code"));
77+
candidates.push(primary_repo_root.join("reference-source").join("hackcode"));
78+
candidates.push(primary_repo_root.join("vendor").join("hackcode"));
7979

8080
let mut deduped = Vec::new();
8181
for candidate in candidates {

rust/crates/plugins/src/lib.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1619,15 +1619,15 @@ fn detect_claude_code_manifest_contract_gaps(
16191619
for (field, detail) in [
16201620
(
16211621
"skills",
1622-
"plugin manifest field `skills` uses the Claude Code plugin contract; `claw` does not load plugin-managed skills and instead discovers skills from local roots such as `.claw/skills`, `.omc/skills`, `.agents/skills`, `~/.omc/skills`, and `~/.claude/skills/omc-learned`.",
1622+
"plugin manifest field `skills` uses the Claude Code plugin contract; `hackcode` does not load plugin-managed skills and instead discovers skills from local roots such as `.hackcode/skills`, `.omc/skills`, `.agents/skills`, `~/.omc/skills`, and `~/.claude/skills/omc-learned`.",
16231623
),
16241624
(
16251625
"mcpServers",
1626-
"plugin manifest field `mcpServers` uses the Claude Code plugin contract; `claw` does not import MCP servers from plugin manifests.",
1626+
"plugin manifest field `mcpServers` uses the Claude Code plugin contract; `hackcode` does not import MCP servers from plugin manifests.",
16271627
),
16281628
(
16291629
"agents",
1630-
"plugin manifest field `agents` uses the Claude Code plugin contract; `claw` does not load plugin-managed agent markdown catalogs from plugin manifests.",
1630+
"plugin manifest field `agents` uses the Claude Code plugin contract; `hackcode` does not load plugin-managed agent markdown catalogs from plugin manifests.",
16311631
),
16321632
] {
16331633
if root.contains_key(field) {
@@ -1643,7 +1643,7 @@ fn detect_claude_code_manifest_contract_gaps(
16431643
.is_some_and(|commands| commands.iter().any(Value::is_string))
16441644
{
16451645
errors.push(PluginManifestValidationError::UnsupportedManifestContract {
1646-
detail: "plugin manifest field `commands` uses Claude Code-style directory globs; `claw` slash dispatch is still built-in and does not load plugin slash command markdown files.".to_string(),
1646+
detail: "plugin manifest field `commands` uses Claude Code-style directory globs; `hackcode` slash dispatch is still built-in and does not load plugin slash command markdown files.".to_string(),
16471647
});
16481648
}
16491649

@@ -1655,7 +1655,7 @@ fn detect_claude_code_manifest_contract_gaps(
16551655
) {
16561656
errors.push(PluginManifestValidationError::UnsupportedManifestContract {
16571657
detail: format!(
1658-
"plugin hook `{hook_name}` uses the Claude Code lifecycle contract; `claw` plugins currently support only PreToolUse, PostToolUse, and PostToolUseFailure."
1658+
"plugin hook `{hook_name}` uses the Claude Code lifecycle contract; `hackcode` plugins currently support only PreToolUse, PostToolUse, and PostToolUseFailure."
16591659
),
16601660
});
16611661
}

0 commit comments

Comments
 (0)