lampson 0.2.5 → 0.2.6
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/chat.syn +8 -4
- package/lib/diff.syn +37 -2
- package/lib/tools/common.syn +13 -0
- package/package.json +1 -1
package/chat.syn
CHANGED
|
@@ -79,6 +79,10 @@ task dim(s)
|
|
|
79
79
|
give c("2", s)
|
|
80
80
|
task yellow(s)
|
|
81
81
|
give c("33", s)
|
|
82
|
+
-- actividad de tools (▸, $): amarillo atenuado, para que el 33 pleno quede solo como "atención
|
|
83
|
+
-- requerida" (⚠ aprobaciones, avisos) — semáforo: actividad ≠ advertencia (2026-08-31)
|
|
84
|
+
task act(s)
|
|
85
|
+
give c("2;33", s)
|
|
82
86
|
task green(s)
|
|
83
87
|
give c("32", s)
|
|
84
88
|
task red(s)
|
|
@@ -276,7 +280,7 @@ task on_event(kind, data, tag)
|
|
|
276
280
|
set pending_call to desc
|
|
277
281
|
otherwise
|
|
278
282
|
set pending_call to ""
|
|
279
|
-
print(" " +
|
|
283
|
+
print(" " + act("▸ " + desc))
|
|
280
284
|
otherwise when kind == "tool_result"
|
|
281
285
|
let out be data["output"]
|
|
282
286
|
let name be data["call"]["name"]
|
|
@@ -284,7 +288,7 @@ task on_event(kind, data, tag)
|
|
|
284
288
|
let d be diff_of(name, out)
|
|
285
289
|
let path be when d != nothing then text(data["call"]["args"]["path"]) otherwise ""
|
|
286
290
|
set turn_outputs to append(turn_outputs, {"name": name, "args": data["call"]["args"], "output": out, "diff": d, "path": path})
|
|
287
|
-
let lead be when pending_call != "" then " " +
|
|
291
|
+
let lead be when pending_call != "" then " " + act("▸ " + pending_call) + " " otherwise " "
|
|
288
292
|
set pending_call to ""
|
|
289
293
|
when d != nothing
|
|
290
294
|
print_diff_with(lead, path, d)
|
|
@@ -1015,7 +1019,7 @@ while running
|
|
|
1015
1019
|
print(dim(" hay " + text(length(turn_outputs)) + " resultados en este turno: /out 1 … /out " + text(length(turn_outputs))))
|
|
1016
1020
|
otherwise
|
|
1017
1021
|
let o be turn_outputs[length(turn_outputs) - back]
|
|
1018
|
-
print(" " +
|
|
1022
|
+
print(" " + act("▸ " + permission.describe_call(o["name"], o["args"])))
|
|
1019
1023
|
print_full(o)
|
|
1020
1024
|
otherwise when starts_with(input, "/trace")
|
|
1021
1025
|
let n be trim(slice(input, 6, length(input)))
|
|
@@ -1354,7 +1358,7 @@ while running
|
|
|
1354
1358
|
when cmd == ""
|
|
1355
1359
|
print(" uso: !<comando> p.ej. !git status · !npm test · !cat .env")
|
|
1356
1360
|
otherwise
|
|
1357
|
-
print(" " +
|
|
1361
|
+
print(" " + act("$ " + cmd))
|
|
1358
1362
|
flush()
|
|
1359
1363
|
let out be run_interactive(cmd)
|
|
1360
1364
|
set messages to append(messages, {"role": "user", "content": "[The user ran this command in the shell themselves]\n$ " + cmd + "\n" + tools.truncate(out, 6000)})
|
package/lib/diff.syn
CHANGED
|
@@ -8,6 +8,10 @@ use "./ui.syn" as ui
|
|
|
8
8
|
|
|
9
9
|
let ESC be decode(bytes("1b", "hex"))
|
|
10
10
|
let LIMIT be 80
|
|
11
|
+
-- corridas largas de +/- se colapsan: HEAD líneas, "⋮ ±N líneas más", TAIL líneas (un rewrite de 200
|
|
12
|
+
-- líneas pintaba 200 rojas + 200 verdes; el diff completo sigue en la UI web, que recibe old/new crudos)
|
|
13
|
+
let HEAD be 4
|
|
14
|
+
let TAIL be 2
|
|
11
15
|
|
|
12
16
|
-- línea de diff con fondo (verde/rojo) rellenada hasta el ancho útil, cortada si se pasa
|
|
13
17
|
task row(color, kind, num, body, width)
|
|
@@ -40,6 +44,26 @@ task lpad(s, n)
|
|
|
40
44
|
set out to " " + out
|
|
41
45
|
give out
|
|
42
46
|
|
|
47
|
+
-- vuelca una corrida de líneas +/- ya formateadas: entera si es corta, colapsada si supera HEAD+TAIL+1
|
|
48
|
+
task flush_run(lines, rows, op, color, width)
|
|
49
|
+
when length(rows) <= HEAD + TAIL + 1
|
|
50
|
+
each r in rows
|
|
51
|
+
set lines to append(lines, r)
|
|
52
|
+
give lines
|
|
53
|
+
let i be 0
|
|
54
|
+
while i < HEAD
|
|
55
|
+
set lines to append(lines, rows[i])
|
|
56
|
+
set i to i + 1
|
|
57
|
+
let hidden be length(rows) - HEAD - TAIL
|
|
58
|
+
let sign be when op == "+" then "+" otherwise "−"
|
|
59
|
+
let code be when op == "+" then "32;2" otherwise "31;2"
|
|
60
|
+
set lines to append(lines, sgr(color, code, lpad("", width) + " ⋮ " + sign + text(hidden) + " líneas más"))
|
|
61
|
+
set i to length(rows) - TAIL
|
|
62
|
+
while i < length(rows)
|
|
63
|
+
set lines to append(lines, rows[i])
|
|
64
|
+
set i to i + 1
|
|
65
|
+
give lines
|
|
66
|
+
|
|
43
67
|
-- LCS clásico: devuelve la lista de ops {"op": " "|"-"|"+", "a": idx_old, "b": idx_new}
|
|
44
68
|
task lcs_ops(a, b)
|
|
45
69
|
let n be length(a)
|
|
@@ -135,6 +159,9 @@ export task diff(old, new, ctx, color)
|
|
|
135
159
|
set idx to idx + 1
|
|
136
160
|
set idx to 0
|
|
137
161
|
let skipping be false
|
|
162
|
+
-- corrida de +/- consecutivos: se junta y se vuelca colapsada (flush_run) al cambiar de tipo
|
|
163
|
+
let run_op be ""
|
|
164
|
+
let run_rows be []
|
|
138
165
|
each o in ops
|
|
139
166
|
let near be false
|
|
140
167
|
let w be idx - ctx
|
|
@@ -142,6 +169,10 @@ export task diff(old, new, ctx, color)
|
|
|
142
169
|
when w >= 0 and w < length(ops) and ops[w]["op"] != " "
|
|
143
170
|
set near to true
|
|
144
171
|
set w to w + 1
|
|
172
|
+
when o["op"] != run_op and run_op != ""
|
|
173
|
+
set lines to flush_run(lines, run_rows, run_op, color, width)
|
|
174
|
+
set run_op to ""
|
|
175
|
+
set run_rows to []
|
|
145
176
|
when o["op"] == " "
|
|
146
177
|
when near
|
|
147
178
|
set lines to append(lines, row(color, " ", text(pre + o["b"] + 1), mid_b[o["b"]], width))
|
|
@@ -150,12 +181,16 @@ export task diff(old, new, ctx, color)
|
|
|
150
181
|
set lines to append(lines, sgr(color, "2", lpad("", width) + " ⋯"))
|
|
151
182
|
set skipping to true
|
|
152
183
|
otherwise when o["op"] == "-"
|
|
153
|
-
set
|
|
184
|
+
set run_op to "-"
|
|
185
|
+
set run_rows to append(run_rows, row(color, "-", text(pre + o["a"] + 1), mid_a[o["a"]], width))
|
|
154
186
|
set skipping to false
|
|
155
187
|
otherwise
|
|
156
|
-
set
|
|
188
|
+
set run_op to "+"
|
|
189
|
+
set run_rows to append(run_rows, row(color, "+", text(pre + o["b"] + 1), mid_b[o["b"]], width))
|
|
157
190
|
set skipping to false
|
|
158
191
|
set idx to idx + 1
|
|
192
|
+
when run_op != ""
|
|
193
|
+
set lines to flush_run(lines, run_rows, run_op, color, width)
|
|
159
194
|
-- contexto posterior (del sufijo común)
|
|
160
195
|
let after_start be length(b) - suf
|
|
161
196
|
let upto be when after_start + ctx < length(b) then after_start + ctx otherwise length(b)
|
package/lib/tools/common.syn
CHANGED
|
@@ -11,6 +11,13 @@ export let ROOT be "workspace"
|
|
|
11
11
|
export let MAX_OUTPUT be 30000
|
|
12
12
|
export let IGNORED_DIRS be [".git", "node_modules", ".synsema", ".lampson", "workspace", "target", "dist", "build", "coverage", "__pycache__", ".venv", ".next", ".netlify", ".cache", ".turbo"]
|
|
13
13
|
|
|
14
|
+
-- true si algún segmento del path es ".." (no cuenta "foo..bar")
|
|
15
|
+
task has_dotdot(p)
|
|
16
|
+
each part in split(p, "/")
|
|
17
|
+
when part == ".."
|
|
18
|
+
give true
|
|
19
|
+
give false
|
|
20
|
+
|
|
14
21
|
-- path del modelo → path real bajo workspace/
|
|
15
22
|
export task ws(path)
|
|
16
23
|
let p be when path == nothing then "." otherwise replace_text(text(path), "\\", "/")
|
|
@@ -22,6 +29,12 @@ export task ws(path)
|
|
|
22
29
|
set p to slice(p, 1, length(p))
|
|
23
30
|
otherwise
|
|
24
31
|
set stripping to false
|
|
32
|
+
-- escape del workspace (C:\… o ..): mensaje instructivo ANTES del runtime. Sin esto el modelo
|
|
33
|
+
-- recibía "Capability not granted: file_write(…)" (con ..) u "os error 123" (con C:\…, que parece
|
|
34
|
+
-- un error de sintaxis de la ruta) y quemaba reintentos probando variantes (visto 2026-08-31:
|
|
35
|
+
-- quiso guardar una "memoria global" fuera del workspace, como el install global de skills).
|
|
36
|
+
when contains(split(p, "/")[0], ":") or has_dotdot(p)
|
|
37
|
+
raise("path escapes the workspace: \"" + text(path) + "\" — file tools only reach the mounted workspace; use paths relative to its root (e.g. \"src/app.ts\"). Do not retry with other path variants. To keep notes across sessions use the memory tool (the harness stores them per project, outside the repo); for anything else outside the workspace, explain what you need and ask the user.")
|
|
25
38
|
when p == "." or p == "" or p == ROOT
|
|
26
39
|
give ROOT
|
|
27
40
|
when starts_with(p, ROOT + "/")
|
package/package.json
CHANGED