lampson 0.2.6 → 0.2.8
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/README.md +16 -10
- package/bin/lampson.js +13 -7
- package/chat.syn +36 -31
- package/lampson.ps1 +11 -1
- package/lampson.sh +7 -0
- package/lib/agents.syn +10 -10
- package/lib/fs.syn +226 -0
- package/lib/loop.syn +9 -8
- package/lib/permission.syn +40 -14
- package/lib/plugins.syn +408 -0
- package/lib/prompt.syn +3 -2
- package/lib/sched_run.syn +10 -10
- package/lib/schedule.syn +36 -21
- package/lib/tools/fetch.syn +573 -0
- package/lib/tools/memo.syn +27 -5
- package/lib/tools/url.syn +220 -0
- package/lib/tools.syn +32 -30
- package/lib/workspaces.syn +34 -9
- package/package.json +12 -4
- package/{lamps/example-hello/lamp.json → plugins/example-hello/plugin.json} +2 -2
- package/plugins/example-hello/plugin.syn +19 -0
- package/public/css/panel.css +3 -3
- package/public/css/sidebar.css +21 -0
- package/public/hub.html +1 -1
- package/public/index.html +3 -3
- package/public/js/app.js +1 -1
- package/public/js/chat.js +4 -4
- package/public/js/core.js +1 -1
- package/public/js/memory.js +2 -1
- package/public/js/{lamps.js → plugins.js} +43 -41
- package/public/js/schedules.js +9 -9
- package/public/js/tree.js +212 -10
- package/public/js/workspaces.js +1 -1
- package/skills/lampson/SKILL.md +26 -11
- package/web.syn +32 -17
- package/lamps/example-hello/lamp.syn +0 -19
- package/lib/lamps.syn +0 -386
package/lib/sched_run.syn
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
-- lib/sched_run.syn — ejecutar UNA tarea programada (
|
|
1
|
+
-- lib/sched_run.syn — ejecutar UNA tarea programada (plugin | bash | prompt) y dejar registro
|
|
2
2
|
--
|
|
3
3
|
-- Separado de lib/schedule.syn porque las corridas `prompt` necesitan agents/loop/provider, y schedule.syn es
|
|
4
4
|
-- importado por tools.syn (que agents.syn importa): acá no hay ciclo. Lo usan web.syn (tick del cron y
|
|
@@ -23,7 +23,7 @@ use "./session.syn" as session
|
|
|
23
23
|
use "./trace.syn" as trace
|
|
24
24
|
use "./permission.syn" as permission
|
|
25
25
|
use "./tools.syn" as tools
|
|
26
|
-
use "./
|
|
26
|
+
use "./plugins.syn" as plugins
|
|
27
27
|
|
|
28
28
|
let PROMPT_NOTE be "\n\n# Scheduled run\n- This is an UNATTENDED scheduled run (no user is watching). Do the task, verify, and finish with a short report: what you found or changed, with paths. Do not ask questions - if something is missing, say so in the report.\n- A permission request may take hours to be answered (the user gets a link). Prefer actions that need no approval; if one is denied, do not retry it - report it.\n- ONLY the workspace is accessible: absolute paths, `..`, home folders, other projects and skill folders outside it do NOT exist for your tools (a `File not found` there is final - never retry). Work with what is inside the workspace and what you already know."
|
|
29
29
|
|
|
@@ -67,8 +67,8 @@ export task run(t, ask_fn, on_event)
|
|
|
67
67
|
require file("workspace/*")
|
|
68
68
|
require file.read("skills")
|
|
69
69
|
require file.read("skills/*")
|
|
70
|
-
require file.read("
|
|
71
|
-
require file.read("
|
|
70
|
+
require file.read("plugins")
|
|
71
|
+
require file.read("plugins/*")
|
|
72
72
|
require file("memory")
|
|
73
73
|
require file("memory/*")
|
|
74
74
|
require file(".lampson")
|
|
@@ -94,11 +94,11 @@ export task run(t, ask_fn, on_event)
|
|
|
94
94
|
let names be where(agents.profile(p)["tools"], (n) => n != "delegate" and n != "mcp" and n != "schedule")
|
|
95
95
|
let reg be tools.registry_subset(names)
|
|
96
96
|
let cat be tools.catalog_subset(names)
|
|
97
|
-
--
|
|
97
|
+
-- plugins encendidos también (las de solo lectura si el perfil no edita)
|
|
98
98
|
let ro be not (p == "build")
|
|
99
|
-
each ln in
|
|
100
|
-
set reg[ln] to "
|
|
101
|
-
set cat to cat +
|
|
99
|
+
each ln in plugins.names(ro)
|
|
100
|
+
set reg[ln] to "plugin"
|
|
101
|
+
set cat to cat + plugins.catalog(ro)
|
|
102
102
|
let asker be ask_fn
|
|
103
103
|
when asker == nothing and t["permission"] == "ask"
|
|
104
104
|
set asker to ask_remote
|
|
@@ -135,8 +135,8 @@ export task tick()
|
|
|
135
135
|
require file("workspace/*")
|
|
136
136
|
require file.read("skills")
|
|
137
137
|
require file.read("skills/*")
|
|
138
|
-
require file.read("
|
|
139
|
-
require file.read("
|
|
138
|
+
require file.read("plugins")
|
|
139
|
+
require file.read("plugins/*")
|
|
140
140
|
require file("memory")
|
|
141
141
|
require file("memory/*")
|
|
142
142
|
require file(".lampson")
|
package/lib/schedule.syn
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
-- lib/schedule.syn — tareas programadas: "cada 6 h", "todos los días a las 9", "lunes 8:30"
|
|
2
2
|
--
|
|
3
3
|
-- Qué se programa (action.type):
|
|
4
|
-
--
|
|
4
|
+
-- plugin → una tool de un plugin ENCENDIDO: {plugin, tool, args}. Encenderlo ya fue la autorización.
|
|
5
5
|
-- bash → un comando fijo desde el workspace: {command, timeout}. Aprobado UNA vez, al crear la tarea.
|
|
6
6
|
-- prompt → una corrida completa del agente con un texto: {prompt, agent}. Sin humano al lado: corre con el
|
|
7
7
|
-- sobre de permisos que se fijó al crearla (permission: strict | ask | yolo). En `ask`, cuando el
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
-- Este módulo no importa agents/loop (ciclo con tools.syn): las corridas `prompt` las hace lib/sched_run.syn.
|
|
24
24
|
|
|
25
25
|
use "./tools/bash.syn" as t_bash
|
|
26
|
-
use "./
|
|
26
|
+
use "./plugins.syn" as plugins
|
|
27
27
|
use "./permission.syn" as permission
|
|
28
28
|
use "./tools/common.syn" as c
|
|
29
29
|
use "./tools/memo.syn" as memo
|
|
@@ -380,15 +380,19 @@ task slug(name)
|
|
|
380
380
|
-- valida y normaliza la acción → {ok, action, error}
|
|
381
381
|
task check_action(action)
|
|
382
382
|
when action == nothing or not contains(action, "type")
|
|
383
|
-
give {"ok": false, "error": "action needs a type:
|
|
383
|
+
give {"ok": false, "error": "action needs a type: plugin | bash | prompt"}
|
|
384
384
|
let kind be lower(text(action["type"]))
|
|
385
385
|
when kind == "lamp"
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
386
|
+
-- compat: "lamp" era el nombre de "plugin" hasta 2026-09 (tareas guardadas, JSON escrito a mano)
|
|
387
|
+
set kind to "plugin"
|
|
388
|
+
when kind == "plugin"
|
|
389
|
+
let pname be plugin_of(action)
|
|
390
|
+
when pname == "" or not contains(action, "tool")
|
|
391
|
+
give {"ok": false, "error": "action plugin needs plugin and tool"}
|
|
392
|
+
let full be plugins.tool_name(pname, text(action["tool"]))
|
|
393
|
+
when not contains(plugins.names(false), full)
|
|
394
|
+
give {"ok": false, "error": "plugin tool " + full + " is not available (the plugin must exist and be ON)"}
|
|
395
|
+
give {"ok": true, "action": {"type": "plugin", "plugin": pname, "tool": text(action["tool"]), "args": when contains(action, "args") then action["args"] otherwise {}}}
|
|
392
396
|
when kind == "bash"
|
|
393
397
|
when not contains(action, "command") or trim(text(action["command"])) == ""
|
|
394
398
|
give {"ok": false, "error": "action bash needs a command"}
|
|
@@ -405,7 +409,7 @@ task check_action(action)
|
|
|
405
409
|
when not contains(["build", "plan", "review", "explore"], agent)
|
|
406
410
|
give {"ok": false, "error": "agent must be build | plan | review | explore"}
|
|
407
411
|
give {"ok": true, "action": {"type": "prompt", "prompt": text(action["prompt"]), "agent": agent}}
|
|
408
|
-
give {"ok": false, "error": "unknown action type '" + kind + "' (
|
|
412
|
+
give {"ok": false, "error": "unknown action type '" + kind + "' (plugin | bash | prompt)"}
|
|
409
413
|
|
|
410
414
|
-- crear: spec = {name, when, action, permission?, approval_timeout?, notify?} → la tarea (raise si es inválida)
|
|
411
415
|
export task add(spec)
|
|
@@ -415,8 +419,8 @@ export task add(spec)
|
|
|
415
419
|
require env("OS")
|
|
416
420
|
require file(".lampson")
|
|
417
421
|
require file(".lampson/*")
|
|
418
|
-
require file.read("
|
|
419
|
-
require file.read("
|
|
422
|
+
require file.read("plugins")
|
|
423
|
+
require file.read("plugins/*")
|
|
420
424
|
require file("workspace")
|
|
421
425
|
require file("workspace/*")
|
|
422
426
|
when spec == nothing or not contains(spec, "when")
|
|
@@ -450,9 +454,20 @@ export task add(spec)
|
|
|
450
454
|
put(t)
|
|
451
455
|
give t
|
|
452
456
|
|
|
457
|
+
-- el nombre del plugin de una acción; acepta la clave vieja "lamp" (tareas guardadas antes de 2026-09)
|
|
458
|
+
task plugin_of(action)
|
|
459
|
+
when contains(action, "plugin")
|
|
460
|
+
give text(action["plugin"])
|
|
461
|
+
when contains(action, "lamp")
|
|
462
|
+
give text(action["lamp"])
|
|
463
|
+
give ""
|
|
464
|
+
|
|
465
|
+
task is_plugin_action(a)
|
|
466
|
+
give a["type"] == "plugin" or a["type"] == "lamp"
|
|
467
|
+
|
|
453
468
|
task default_name(action)
|
|
454
|
-
when action
|
|
455
|
-
give action
|
|
469
|
+
when is_plugin_action(action)
|
|
470
|
+
give plugin_of(action) + " " + action["tool"]
|
|
456
471
|
when action["type"] == "bash"
|
|
457
472
|
let cmd be action["command"]
|
|
458
473
|
give when length(cmd) > 40 then slice(cmd, 0, 40) + "…" otherwise cmd
|
|
@@ -533,7 +548,7 @@ export task heartbeat()
|
|
|
533
548
|
write_file(HEARTBEAT, text(now()))
|
|
534
549
|
give true
|
|
535
550
|
|
|
536
|
-
-- ---------- corridas:
|
|
551
|
+
-- ---------- corridas: plugin y bash (prompt en sched_run.syn) ----------
|
|
537
552
|
export task run_simple(t)
|
|
538
553
|
require exec
|
|
539
554
|
require time
|
|
@@ -541,13 +556,13 @@ export task run_simple(t)
|
|
|
541
556
|
require env("OS")
|
|
542
557
|
require file(".lampson")
|
|
543
558
|
require file(".lampson/*")
|
|
544
|
-
require file.read("
|
|
545
|
-
require file.read("
|
|
559
|
+
require file.read("plugins")
|
|
560
|
+
require file.read("plugins/*")
|
|
546
561
|
require file("workspace")
|
|
547
562
|
require file("workspace/*")
|
|
548
563
|
let a be t["action"]
|
|
549
|
-
when a
|
|
550
|
-
give
|
|
564
|
+
when is_plugin_action(a)
|
|
565
|
+
give plugins.call(plugins.tool_name(plugin_of(a), a["tool"]), a["args"])
|
|
551
566
|
when a["type"] == "bash"
|
|
552
567
|
let v be permission.evaluate("bash", {"command": a["command"]}, "yolo")
|
|
553
568
|
when v["decision"] == "deny"
|
|
@@ -640,8 +655,8 @@ export task log_tail(id, n)
|
|
|
640
655
|
|
|
641
656
|
-- descripción de la acción (una línea) para previews y listados
|
|
642
657
|
export task describe_action(a)
|
|
643
|
-
when a
|
|
644
|
-
give "
|
|
658
|
+
when is_plugin_action(a)
|
|
659
|
+
give "plugin " + plugin_of(a) + "." + a["tool"] + (when length(keys(a["args"])) > 0 then " " + one_line(json_encode(a["args"]), 80) otherwise "")
|
|
645
660
|
when a["type"] == "bash"
|
|
646
661
|
give "$ " + one_line(a["command"], 120)
|
|
647
662
|
give "agent " + a["agent"] + ": " + one_line(a["prompt"], 140)
|