Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,20 @@ apt install clang llvm

## Install the Claude Code skill

The skill teaches Claude how to emit LLVM IR, use the module system, and build native binaries. It lives in `.claude/skills/smlt/SKILL.md` inside the core repo.
The skill teaches Claude how to emit LLVM IR, use the module system, and build native binaries.

**For projects inside the core repo** — it works automatically. Claude picks it up from the project directory.

**For any other project** — copy the skill into your project's `.claude/skills/` directory:
**For any other project** — run from your project directory:

```bash
mkdir -p /path/to/your/project/.claude/skills/smlt
cp "$SMLT_HOME/.claude/skills/smlt/SKILL.md" /path/to/your/project/.claude/skills/smlt/
smlt install-skill
```

Then point it at the toolchain by adding to your project's `CLAUDE.md`:
This downloads the latest skill into `.claude/skills/smlt/`. For Codex or other agents that use `.agents/`:

```
The smlt toolchain is at $SMLT_HOME (or the absolute path).
```bash
smlt install-skill --agents
```

## Usage
Expand All @@ -67,6 +66,7 @@ smlt cross app.ll myapp --auto # cross-compile for all platforms
smlt install app.ll # build and install to $SMLT_HOME/bin/
smlt run app.ll -- args # build to temp, execute, clean up
smlt fetch <module> # fetch module from registry
smlt install-skill # install Claude Code skill
smlt doctor # check build environment
```

Expand Down
87 changes: 85 additions & 2 deletions apps/smlt/smlt.ll
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
; smlt run <app.ll> [opts] [-- args] Build to temp and execute
; smlt doctor Show build environment
; smlt fetch <module> Fetch module from git (core or URL path)
; smlt install-skill [--agents] Install Claude Code skill file
; smlt modules List locally installed modules
; smlt info <module> Show module info (local first, then registry)
; smlt search <query> GET /v1/search/<query>
Expand Down Expand Up @@ -156,8 +157,21 @@ declare i32 @proc_exec_capture(ptr, ptr, i64, ptr)
@_s_cross = private constant [5 x i8] c"cross"
@_s_doctor = private constant [6 x i8] c"doctor"
@_s_install = private constant [7 x i8] c"install"
@_s_install_skill = private constant [13 x i8] c"install-skill"
@_s_run_cmd = private constant [3 x i8] c"run"

; install-skill constants
; "curl -fsSL https://github.com/smltdev/smlt/releases/latest/download/smlt.skill | tar xz -C " = 90 bytes
; c(1) u(2) r(3) l(4) (5) -(6) f(7) s(8) s(9) L(10) (11) h(12) t(13) t(14) p(15) s(16) :(17) /(18) /(19) g(20) i(21) t(22) h(23) u(24) b(25) .(26) c(27) o(28) m(29) /(30) s(31) m(32) l(33) t(34) d(35) e(36) v(37) /(38) s(39) m(40) l(41) t(42) /(43) r(44) e(45) l(46) e(47) a(48) s(49) e(50) s(51) /(52) l(53) a(54) t(55) e(56) s(57) t(58) /(59) d(60) o(61) w(62) n(63) l(64) o(65) a(66) d(67) /(68) s(69) m(70) l(71) t(72) .(73) s(74) k(75) i(76) l(77) l(78) (79) |(80) (81) t(82) a(83) r(84) (85) x(86) z(87) (88) -(89) C(90) (91) = 91
@_s_skill_curl_prefix = private constant [91 x i8] c"curl -fsSL https://github.com/smltdev/smlt/releases/latest/download/smlt.skill | tar xz -C "
@_s_skill_dir_claude = private constant [20 x i8] c".claude/skills/smlt/"
@_s_skill_dir_agents = private constant [20 x i8] c".agents/skills/smlt/"
@_s_agents_flag = private constant [8 x i8] c"--agents"
@_s_skill_installed = private constant [22 x i8] c"Skill installed to: \00\00"
@_s_skill_err = private constant [28 x i8] c"Error: install-skill failed\0A"
@_s_sh_path = private constant [8 x i8] c"/bin/sh\00"
@_s_sh_c_flag = private constant [3 x i8] c"-c\00"

; Platform names (without null)
@_s_plat_darwin_arm64 = private constant [12 x i8] c"darwin-arm64"
@_s_plat_darwin_x86_64 = private constant [13 x i8] c"darwin-x86_64"
Expand Down Expand Up @@ -292,6 +306,8 @@ declare i32 @proc_exec_capture(ptr, ptr, i64, ptr)
@_s_h_env = private constant [11 x i8] c"Environment"
@_s_h_cinstall = private constant [25 x i8] c"install <app.ll> [opts] "
@_s_h_crun = private constant [27 x i8] c"run <app.ll> [opts] [-- ..]"
@_s_h_cis = private constant [24 x i8] c"install-skill [--agents]"
@_s_h_dis = private constant [31 x i8] c"Install Claude Code skill file "
@_s_h_cm = private constant [7 x i8] c"modules"
@_s_h_dm = private constant [30 x i8] c"List locally installed modules"
@_s_h_ci = private constant [13 x i8] c"info <module>"
Expand Down Expand Up @@ -3049,7 +3065,11 @@ check_run:

check_fetch:
%is_fetch = call i1 @str_eq(ptr %cmd, i64 %cmdlen, ptr @_s_fetch, i64 5)
br i1 %is_fetch, label %do_fetch_cmd, label %check_modules
br i1 %is_fetch, label %do_fetch_cmd, label %check_install_skill

check_install_skill:
%is_install_skill = call i1 @str_eq(ptr %cmd, i64 %cmdlen, ptr @_s_install_skill, i64 13)
br i1 %is_install_skill, label %do_install_skill, label %check_modules

check_modules:
%is_modules = call i1 @str_eq(ptr %cmd, i64 %cmdlen, ptr @_s_modules_cmd, i64 7)
Expand Down Expand Up @@ -3131,6 +3151,68 @@ err_home:
call i64 @write(i32 2, ptr @_s_newline, i64 1)
ret i32 1

; === install-skill ===
do_install_skill:
; Check for --agents flag
%is_has_agents = call i1 @cli_has_flag(i32 %argc, ptr %argv, ptr @_s_agents_flag, i64 8)
; Select target dir: .agents/skills/smlt/ or .claude/skills/smlt/
%is_dir_ptr = select i1 %is_has_agents, ptr @_s_skill_dir_agents, ptr @_s_skill_dir_claude
%is_dir_len = select i1 %is_has_agents, i64 20, i64 20

; mkdir -p <target_dir> via argv: ["/usr/bin/env", "mkdir", "-p", dir, null]
%is_mkdir_dir = alloca [64 x i8], align 1
call ptr @memcpy(ptr %is_mkdir_dir, ptr %is_dir_ptr, i64 %is_dir_len)
%is_mkdir_null = getelementptr i8, ptr %is_mkdir_dir, i64 %is_dir_len
store i8 0, ptr %is_mkdir_null
%is_mkdir_argv = alloca [5 x ptr], align 8
%is_ma0 = getelementptr ptr, ptr %is_mkdir_argv, i64 0
store ptr @_s_env_path, ptr %is_ma0
%is_ma1 = getelementptr ptr, ptr %is_mkdir_argv, i64 1
store ptr @_s_mkdir_cmd, ptr %is_ma1
%is_ma2 = getelementptr ptr, ptr %is_mkdir_argv, i64 2
store ptr @_s_mkdir_p_flag, ptr %is_ma2
%is_ma3 = getelementptr ptr, ptr %is_mkdir_argv, i64 3
store ptr %is_mkdir_dir, ptr %is_ma3
%is_ma4 = getelementptr ptr, ptr %is_mkdir_argv, i64 4
store ptr null, ptr %is_ma4
%is_mk_rc = call i32 @proc_exec(ptr %is_mkdir_argv)

; Build shell command string: curl ... | tar xz -C <dir>
%is_cmd = alloca [512 x i8], align 1
%is_pos = alloca i64, align 8
store i64 0, ptr %is_pos
call void @buf_mem(ptr %is_cmd, ptr %is_pos, ptr @_s_skill_curl_prefix, i64 91)
call void @buf_mem(ptr %is_cmd, ptr %is_pos, ptr %is_dir_ptr, i64 %is_dir_len)
; Null-terminate
%is_clen = load i64, ptr %is_pos
%is_cnull = getelementptr i8, ptr %is_cmd, i64 %is_clen
store i8 0, ptr %is_cnull

; Run via sh -c "<cmd>" since we need pipe
%is_argv = alloca [4 x ptr], align 8
%is_a0 = getelementptr ptr, ptr %is_argv, i64 0
store ptr @_s_sh_path, ptr %is_a0
%is_a1 = getelementptr ptr, ptr %is_argv, i64 1
store ptr @_s_sh_c_flag, ptr %is_a1
%is_a2 = getelementptr ptr, ptr %is_argv, i64 2
store ptr %is_cmd, ptr %is_a2
%is_a3 = getelementptr ptr, ptr %is_argv, i64 3
store ptr null, ptr %is_a3

%is_rc = call i32 @proc_exec(ptr %is_argv)
%is_ok = icmp eq i32 %is_rc, 0
br i1 %is_ok, label %is_success, label %is_fail

is_success:
call i64 @write(i32 1, ptr @_s_skill_installed, i64 20)
call i64 @write(i32 1, ptr %is_dir_ptr, i64 %is_dir_len)
call i64 @write(i32 1, ptr @_s_newline, i64 1)
ret i32 0

is_fail:
call i64 @write(i32 2, ptr @_s_skill_err, i64 28)
ret i32 1

; === modules (list locally installed modules) ===
do_modules_cmd:
%mod_home_ok = icmp sge i64 %home_len_val, 0
Expand Down Expand Up @@ -3631,7 +3713,7 @@ verify_fail:

; === Help ===
show_help:
%hbuf = alloca [4096 x i8], align 8
%hbuf = alloca [8192 x i8], align 8
%hpos = alloca i64, align 8
store i64 0, ptr %hpos
call void @cli_help_line(ptr %hbuf, ptr %hpos, ptr @_s_h_title, i64 40)
Expand All @@ -3646,6 +3728,7 @@ show_help:
call void @cli_help_row(ptr %hbuf, ptr %hpos, ptr @_s_h_cd, i64 6, ptr @_s_h_dd, i64 22, i64 32)
call void @cli_help_row(ptr %hbuf, ptr %hpos, ptr @_s_h_cf, i64 14, ptr @_s_h_df, i64 23, i64 32)
call void @cli_help_row(ptr %hbuf, ptr %hpos, ptr @_s_h_ci, i64 13, ptr @_s_h_di, i64 23, i64 32)
call void @cli_help_row(ptr %hbuf, ptr %hpos, ptr @_s_h_cis, i64 24, ptr @_s_h_dis, i64 31, i64 32)
call void @cli_help_row(ptr %hbuf, ptr %hpos, ptr @_s_h_cm, i64 7, ptr @_s_h_dm, i64 30, i64 32)
call void @cli_help_row(ptr %hbuf, ptr %hpos, ptr @_s_h_cs, i64 14, ptr @_s_h_ds, i64 18, i64 32)
call void @cli_help_row(ptr %hbuf, ptr %hpos, ptr @_s_h_cp, i64 13, ptr @_s_h_dp, i64 26, i64 32)
Expand Down