lampson 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lampson.cmd CHANGED
@@ -1,4 +1,4 @@
1
- @echo off
2
- rem lampson.cmd — shim para usar `lampson` desde cualquier carpeta (cmd o PowerShell) una vez en el PATH.
3
- rem El directorio actual pasa a ser el workspace (ver lampson.ps1).
4
- pwsh -NoProfile -ExecutionPolicy Bypass -File "%~dp0lampson.ps1" %*
1
+ @echo off
2
+ rem lampson.cmd — shim para usar `lampson` desde cualquier carpeta (cmd o PowerShell) una vez en el PATH.
3
+ rem El directorio actual pasa a ser el workspace (ver lampson.ps1).
4
+ pwsh -NoProfile -ExecutionPolicy Bypass -File "%~dp0lampson.ps1" %*
package/lampson.ps1 CHANGED
@@ -1,88 +1,88 @@
1
- # lampson.ps1 — launcher Windows. Monta el proyecto como ./workspace (junction) y arranca.
2
- #
3
- # cd C:\mi\proyecto ; lampson # el directorio ACTUAL es el workspace (REPL)
4
- # cd C:\mi\proyecto ; lampson --web # servidor web en http://127.0.0.1:8080 (también -Web)
5
- # lampson --workspace C:\otro\proyecto # elegir la ubicación explícitamente (también -Workspace)
6
- # lampson --agent plan # perfil inicial: build | plan | review | explore
7
- # lampson --yolo | --strict | --ask # permisos para comandos peligrosos (--dangerously-skip-permissions = --yolo)
8
- # lampson --update # actualizar Lampson (git pull) y salir
9
- # lampson --help
10
- #
11
- # Por qué una junction: el scope file("./*") de Synsema v0.6.7 equivale a "*" (disco entero); el scope
12
- # file("workspace/*") sí confina. Montar el proyecto bajo un nombre literal es lo que hace real el
13
- # least-privilege de las tools (mismo modelo mental que `docker -v proyecto:/workspace`).
14
- $ErrorActionPreference = "Stop"
15
- $here = Split-Path -Parent $MyInvocation.MyCommand.Path
16
- $caller = (Get-Location).Path
17
- $mount = Join-Path $here "workspace"
18
-
19
- # --- args: acepta --flag y -Flag, sin distinguir mayúsculas ---
20
- $Workspace = ""; $Web = $false; $Agent = ""; $Perm = ""
21
- $i = 0
22
- while ($i -lt $args.Count) {
23
- $a = [string]$args[$i]
24
- switch -Regex ($a.ToLower()) {
25
- '^--?(web|w)$' { $Web = $true }
26
- '^--?(workspace|ws)$' { $i++; $Workspace = [string]$args[$i] }
27
- '^--?(agent|a)$' { $i++; $Agent = [string]$args[$i] }
28
- '^--?(yolo|y|dangerously-skip-permissions)$' { $Perm = "yolo" }
29
- '^--?(strict|s)$' { $Perm = "strict" }
30
- '^--?(ask)$' { $Perm = "ask" }
31
- '^--?(permission|p)$' { $i++; $Perm = ([string]$args[$i]).ToLower() }
32
- '^--?(update|u)$' { Write-Host "actualizando Lampson en $here"; git -C $here pull --ff-only origin main; Write-Host ("lampson " + (git -C $here rev-parse --short HEAD)); exit $LASTEXITCODE }
33
- '^--?(help|h|\?)$' { Get-Content $PSCommandPath | Select-Object -Skip 1 -First 9 | ForEach-Object { $_.TrimStart('#',' ') }; exit 0 }
34
- default { if ($Workspace -eq "" -and -not $a.StartsWith("-")) { $Workspace = $a } else { Write-Error "argumento desconocido: $a (probá lampson --help)"; exit 1 } }
35
- }
36
- $i++
37
- }
38
-
39
- # --- resolver el proyecto: explícito > directorio actual (si no es el propio lampson) > montado previo ---
40
- if ($Workspace -eq "" -and $caller -ne $here) { $Workspace = $caller }
41
- if ($Workspace -ne "") {
42
- if (-not (Test-Path -LiteralPath $Workspace -PathType Container)) { Write-Error "el workspace no existe o no es un directorio: $Workspace"; exit 1 }
43
- $target = (Resolve-Path -LiteralPath $Workspace).Path
44
- $home_ = [Environment]::GetFolderPath("UserProfile")
45
- if ($target.TrimEnd('\') -eq $home_.TrimEnd('\') -or $target -match '^[A-Za-z]:\\?$') {
46
- Write-Error "'$target' es tu carpeta personal / la raíz del disco, no un proyecto. Entrá al repo (cd) y volvé a correr lampson, o usá --workspace C:\ruta\al\proyecto"; exit 1
47
- }
48
- if ($target -eq $here) { Write-Error "no montes el propio directorio de lampson como workspace desde fuera; usá --workspace"; exit 1 }
49
- if (Test-Path -LiteralPath $mount) {
50
- $item = Get-Item -LiteralPath $mount -Force
51
- if ($item.LinkType -ne "Junction") { Write-Error "./workspace existe y no es una junction; movelo antes de montar otro proyecto"; exit 1 }
52
- $item.Delete()
53
- }
54
- New-Item -ItemType Junction -Path $mount -Target $target | Out-Null
55
- } elseif (-not (Test-Path -LiteralPath $mount)) {
56
- Write-Error "no hay workspace: corré lampson desde el directorio del proyecto, o lampson --workspace C:\ruta"; exit 1
57
- }
58
- $target = (Get-Item -LiteralPath $mount -Force).Target
59
- if ($target -is [array]) { $target = $target[0] }
60
-
61
- # --- skills externas globales (npx skills add -g → ~/.agents/skills; las de Claude Code → ~/.claude/skills) ---
62
- # Se montan como junction bajo .lampson/ porque una capability no puede apuntar a una ruta dinámica (HOME).
63
- $skillMounts = @{ "skills-global" = (Join-Path $HOME ".agents\skills"); "skills-claude" = (Join-Path $HOME ".claude\skills") }
64
- New-Item -ItemType Directory -Force (Join-Path $here ".lampson") | Out-Null
65
- foreach ($k in $skillMounts.Keys) {
66
- $link = Join-Path $here ".lampson\$k"; $src = $skillMounts[$k]
67
- if (Test-Path -LiteralPath $link) { $li = Get-Item -LiteralPath $link -Force; if ($li.LinkType -eq "Junction") { $li.Delete() } }
68
- if (Test-Path -LiteralPath $src -PathType Container) { New-Item -ItemType Junction -Path $link -Target $src | Out-Null }
69
- }
70
-
71
- # --- arrancar desde el directorio de lampson (ahí viven .env, lib/, skills/, .lampson/) ---
72
- # Push/Pop: si PowerShell ejecuta este .ps1 en la shell del usuario (pasa cuando lampson.ps1 y lampson.cmd
73
- # comparten nombre en el PATH), el cwd del usuario debe quedar como estaba al salir.
74
- Push-Location $here
75
- try {
76
- $env:LAMPSON_WORKSPACE = $target
77
- if ($Agent -ne "") { $env:LAMPSON_AGENT = $Agent }
78
- if ($Perm -ne "") { $env:LAMPSON_PERMISSION = $Perm }
79
- if ($Web) {
80
- Write-Host "Lampson web · workspace: $target"
81
- Write-Host "abrí http://127.0.0.1:8080 (Ctrl+C para parar)"
82
- synsema serve web.syn
83
- } else {
84
- synsema run chat.syn
85
- }
86
- } finally {
87
- Pop-Location
88
- }
1
+ # lampson.ps1 — launcher Windows. Monta el proyecto como ./workspace (junction) y arranca.
2
+ #
3
+ # cd C:\mi\proyecto ; lampson # el directorio ACTUAL es el workspace (REPL)
4
+ # cd C:\mi\proyecto ; lampson --web # servidor web en http://127.0.0.1:8080 (también -Web)
5
+ # lampson --workspace C:\otro\proyecto # elegir la ubicación explícitamente (también -Workspace)
6
+ # lampson --agent plan # perfil inicial: build | plan | review | explore
7
+ # lampson --yolo | --strict | --ask # permisos para comandos peligrosos (--dangerously-skip-permissions = --yolo)
8
+ # lampson --update # actualizar Lampson (git pull) y salir
9
+ # lampson --help
10
+ #
11
+ # Por qué una junction: el scope file("./*") de Synsema v0.6.7 equivale a "*" (disco entero); el scope
12
+ # file("workspace/*") sí confina. Montar el proyecto bajo un nombre literal es lo que hace real el
13
+ # least-privilege de las tools (mismo modelo mental que `docker -v proyecto:/workspace`).
14
+ $ErrorActionPreference = "Stop"
15
+ $here = Split-Path -Parent $MyInvocation.MyCommand.Path
16
+ $caller = (Get-Location).Path
17
+ $mount = Join-Path $here "workspace"
18
+
19
+ # --- args: acepta --flag y -Flag, sin distinguir mayúsculas ---
20
+ $Workspace = ""; $Web = $false; $Agent = ""; $Perm = ""
21
+ $i = 0
22
+ while ($i -lt $args.Count) {
23
+ $a = [string]$args[$i]
24
+ switch -Regex ($a.ToLower()) {
25
+ '^--?(web|w)$' { $Web = $true }
26
+ '^--?(workspace|ws)$' { $i++; $Workspace = [string]$args[$i] }
27
+ '^--?(agent|a)$' { $i++; $Agent = [string]$args[$i] }
28
+ '^--?(yolo|y|dangerously-skip-permissions)$' { $Perm = "yolo" }
29
+ '^--?(strict|s)$' { $Perm = "strict" }
30
+ '^--?(ask)$' { $Perm = "ask" }
31
+ '^--?(permission|p)$' { $i++; $Perm = ([string]$args[$i]).ToLower() }
32
+ '^--?(update|u)$' { Write-Host "actualizando Lampson en $here"; git -C $here pull --ff-only origin main; Write-Host ("lampson " + (git -C $here rev-parse --short HEAD)); exit $LASTEXITCODE }
33
+ '^--?(help|h|\?)$' { Get-Content $PSCommandPath | Select-Object -Skip 1 -First 9 | ForEach-Object { $_.TrimStart('#',' ') }; exit 0 }
34
+ default { if ($Workspace -eq "" -and -not $a.StartsWith("-")) { $Workspace = $a } else { Write-Error "argumento desconocido: $a (probá lampson --help)"; exit 1 } }
35
+ }
36
+ $i++
37
+ }
38
+
39
+ # --- resolver el proyecto: explícito > directorio actual (si no es el propio lampson) > montado previo ---
40
+ if ($Workspace -eq "" -and $caller -ne $here) { $Workspace = $caller }
41
+ if ($Workspace -ne "") {
42
+ if (-not (Test-Path -LiteralPath $Workspace -PathType Container)) { Write-Error "el workspace no existe o no es un directorio: $Workspace"; exit 1 }
43
+ $target = (Resolve-Path -LiteralPath $Workspace).Path
44
+ $home_ = [Environment]::GetFolderPath("UserProfile")
45
+ if ($target.TrimEnd('\') -eq $home_.TrimEnd('\') -or $target -match '^[A-Za-z]:\\?$') {
46
+ Write-Error "'$target' es tu carpeta personal / la raíz del disco, no un proyecto. Entrá al repo (cd) y volvé a correr lampson, o usá --workspace C:\ruta\al\proyecto"; exit 1
47
+ }
48
+ if ($target -eq $here) { Write-Error "no montes el propio directorio de lampson como workspace desde fuera; usá --workspace"; exit 1 }
49
+ if (Test-Path -LiteralPath $mount) {
50
+ $item = Get-Item -LiteralPath $mount -Force
51
+ if ($item.LinkType -ne "Junction") { Write-Error "./workspace existe y no es una junction; movelo antes de montar otro proyecto"; exit 1 }
52
+ $item.Delete()
53
+ }
54
+ New-Item -ItemType Junction -Path $mount -Target $target | Out-Null
55
+ } elseif (-not (Test-Path -LiteralPath $mount)) {
56
+ Write-Error "no hay workspace: corré lampson desde el directorio del proyecto, o lampson --workspace C:\ruta"; exit 1
57
+ }
58
+ $target = (Get-Item -LiteralPath $mount -Force).Target
59
+ if ($target -is [array]) { $target = $target[0] }
60
+
61
+ # --- skills externas globales (npx skills add -g → ~/.agents/skills; las de Claude Code → ~/.claude/skills) ---
62
+ # Se montan como junction bajo .lampson/ porque una capability no puede apuntar a una ruta dinámica (HOME).
63
+ $skillMounts = @{ "skills-global" = (Join-Path $HOME ".agents\skills"); "skills-claude" = (Join-Path $HOME ".claude\skills") }
64
+ New-Item -ItemType Directory -Force (Join-Path $here ".lampson") | Out-Null
65
+ foreach ($k in $skillMounts.Keys) {
66
+ $link = Join-Path $here ".lampson\$k"; $src = $skillMounts[$k]
67
+ if (Test-Path -LiteralPath $link) { $li = Get-Item -LiteralPath $link -Force; if ($li.LinkType -eq "Junction") { $li.Delete() } }
68
+ if (Test-Path -LiteralPath $src -PathType Container) { New-Item -ItemType Junction -Path $link -Target $src | Out-Null }
69
+ }
70
+
71
+ # --- arrancar desde el directorio de lampson (ahí viven .env, lib/, skills/, .lampson/) ---
72
+ # Push/Pop: si PowerShell ejecuta este .ps1 en la shell del usuario (pasa cuando lampson.ps1 y lampson.cmd
73
+ # comparten nombre en el PATH), el cwd del usuario debe quedar como estaba al salir.
74
+ Push-Location $here
75
+ try {
76
+ $env:LAMPSON_WORKSPACE = $target
77
+ if ($Agent -ne "") { $env:LAMPSON_AGENT = $Agent }
78
+ if ($Perm -ne "") { $env:LAMPSON_PERMISSION = $Perm }
79
+ if ($Web) {
80
+ Write-Host "Lampson web · workspace: $target"
81
+ Write-Host "abrí http://127.0.0.1:8080 (Ctrl+C para parar)"
82
+ synsema serve web.syn
83
+ } else {
84
+ synsema run chat.syn
85
+ }
86
+ } finally {
87
+ Pop-Location
88
+ }
package/lampson.sh CHANGED
@@ -1,42 +1,42 @@
1
- #!/usr/bin/env bash
2
- # lampson.sh — launcher unix. El directorio ACTUAL es el workspace (o --workspace /ruta).
3
- # cd /mi/proyecto && lampson # REPL (con lampson/ en el PATH)
4
- # cd /mi/proyecto && lampson --web # servidor web en http://127.0.0.1:8080
5
- # lampson --workspace /otro/proyecto [--web] [--agent plan]
6
- set -euo pipefail
7
- here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8
- caller="$(pwd)"
9
- ws=""; web=0
10
- while [ $# -gt 0 ]; do
11
- case "$1" in
12
- --web) web=1 ;;
13
- --workspace) shift; ws="$1" ;;
14
- --agent) shift; export LAMPSON_AGENT="$1" ;;
15
- --yolo|--dangerously-skip-permissions) export LAMPSON_PERMISSION=yolo ;;
16
- --strict) export LAMPSON_PERMISSION=strict ;;
17
- --ask) export LAMPSON_PERMISSION=ask ;;
18
- --update) echo "actualizando Lampson en $here"; git -C "$here" pull --ff-only origin main; echo "lampson $(git -C "$here" rev-parse --short HEAD)"; exit $? ;;
19
- *) echo "uso: lampson [--web] [--workspace RUTA] [--agent PERFIL] [--yolo|--strict|--ask] [--update]" >&2; exit 1 ;;
20
- esac
21
- shift
22
- done
23
- [ -z "$ws" ] && [ "$caller" != "$here" ] && ws="$caller"
24
- if [ -n "$ws" ]; then
25
- [ -d "$ws" ] || { echo "el workspace no existe o no es un directorio: $ws" >&2; exit 1; }
26
- ws="$(cd "$ws" && pwd)"
27
- if [ -e "$here/workspace" ] && [ ! -L "$here/workspace" ]; then echo "./workspace existe y no es un symlink" >&2; exit 1; fi
28
- rm -f "$here/workspace"; ln -s "$ws" "$here/workspace"
29
- elif [ ! -e "$here/workspace" ]; then
30
- echo "no hay workspace: corré lampson desde el directorio del proyecto, o --workspace /ruta" >&2; exit 1
31
- fi
32
- export LAMPSON_WORKSPACE="$(readlink -f "$here/workspace")"
33
- # skills externas globales (npx skills add -g → ~/.agents/skills; Claude Code → ~/.claude/skills), montadas bajo .lampson/
34
- mkdir -p "$here/.lampson"
35
- for pair in "skills-global:$HOME/.agents/skills" "skills-claude:$HOME/.claude/skills"; do
36
- link="$here/.lampson/${pair%%:*}"; src="${pair#*:}"
37
- [ -L "$link" ] && rm -f "$link"
38
- [ -d "$src" ] && ln -s "$src" "$link"
39
- done
40
- echo "workspace -> $LAMPSON_WORKSPACE"
41
- cd "$here"
42
- if [ "$web" = 1 ]; then echo "web: http://127.0.0.1:8080"; exec synsema serve web.syn; else exec synsema run chat.syn; fi
1
+ #!/usr/bin/env bash
2
+ # lampson.sh — launcher unix. El directorio ACTUAL es el workspace (o --workspace /ruta).
3
+ # cd /mi/proyecto && lampson # REPL (con lampson/ en el PATH)
4
+ # cd /mi/proyecto && lampson --web # servidor web en http://127.0.0.1:8080
5
+ # lampson --workspace /otro/proyecto [--web] [--agent plan]
6
+ set -euo pipefail
7
+ here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8
+ caller="$(pwd)"
9
+ ws=""; web=0
10
+ while [ $# -gt 0 ]; do
11
+ case "$1" in
12
+ --web) web=1 ;;
13
+ --workspace) shift; ws="$1" ;;
14
+ --agent) shift; export LAMPSON_AGENT="$1" ;;
15
+ --yolo|--dangerously-skip-permissions) export LAMPSON_PERMISSION=yolo ;;
16
+ --strict) export LAMPSON_PERMISSION=strict ;;
17
+ --ask) export LAMPSON_PERMISSION=ask ;;
18
+ --update) echo "actualizando Lampson en $here"; git -C "$here" pull --ff-only origin main; echo "lampson $(git -C "$here" rev-parse --short HEAD)"; exit $? ;;
19
+ *) echo "uso: lampson [--web] [--workspace RUTA] [--agent PERFIL] [--yolo|--strict|--ask] [--update]" >&2; exit 1 ;;
20
+ esac
21
+ shift
22
+ done
23
+ [ -z "$ws" ] && [ "$caller" != "$here" ] && ws="$caller"
24
+ if [ -n "$ws" ]; then
25
+ [ -d "$ws" ] || { echo "el workspace no existe o no es un directorio: $ws" >&2; exit 1; }
26
+ ws="$(cd "$ws" && pwd)"
27
+ if [ -e "$here/workspace" ] && [ ! -L "$here/workspace" ]; then echo "./workspace existe y no es un symlink" >&2; exit 1; fi
28
+ rm -f "$here/workspace"; ln -s "$ws" "$here/workspace"
29
+ elif [ ! -e "$here/workspace" ]; then
30
+ echo "no hay workspace: corré lampson desde el directorio del proyecto, o --workspace /ruta" >&2; exit 1
31
+ fi
32
+ export LAMPSON_WORKSPACE="$(readlink -f "$here/workspace")"
33
+ # skills externas globales (npx skills add -g → ~/.agents/skills; Claude Code → ~/.claude/skills), montadas bajo .lampson/
34
+ mkdir -p "$here/.lampson"
35
+ for pair in "skills-global:$HOME/.agents/skills" "skills-claude:$HOME/.claude/skills"; do
36
+ link="$here/.lampson/${pair%%:*}"; src="${pair#*:}"
37
+ [ -L "$link" ] && rm -f "$link"
38
+ [ -d "$src" ] && ln -s "$src" "$link"
39
+ done
40
+ echo "workspace -> $LAMPSON_WORKSPACE"
41
+ cd "$here"
42
+ if [ "$web" = 1 ]; then echo "web: http://127.0.0.1:8080"; exec synsema serve web.syn; else exec synsema run chat.syn; fi