Skip to content

Commit 1497ad2

Browse files
�[38;5;243m 1�[0m �[38;5;249mfeat: quality gates, PRD scoping, and Claude Code HITL ports�[0m
�[38;5;243m 2�[0m �[38;5;243m 3�[0m �[38;5;249mShip deterministic smoke/QA evidence, structured clarify interviews with�[0m �[38;5;243m 4�[0m �[38;5;249mtask PRDs, plan/shell approval, context compact, wave rewind, hooks, and�[0m �[38;5;243m 5�[0m �[38;5;249mthin MCP — with longer planner timeouts so slow local SLMs finish reliably.�[0m �[38;5;243m 6�[0m Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent be503b1 commit 1497ad2

62 files changed

Lines changed: 5432 additions & 549 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.slmcode-hooks.example.json‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"hooks": {
3+
"PreToolUse": [
4+
{
5+
"matcher": "ws_shell",
6+
"command": "echo \"PreToolUse shell: $SLMCODE_HOOK_TOOL\" >&2; exit 0",
7+
"timeout_sec": 10
8+
}
9+
],
10+
"PostToolUse": [
11+
{
12+
"matcher": "ws_write|ws_edit|ws_patch",
13+
"command": "python -m compileall -q . 2>/dev/null || true",
14+
"timeout_sec": 60
15+
}
16+
]
17+
}
18+
}

‎TODO.md‎

Lines changed: 22 additions & 285 deletions
Large diffs are not rendered by default.

‎cmd/slmcode/cmd_tui.go‎

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import (
1414
"github.com/UnicoLab/slmcode/pkg/cli"
1515
"github.com/UnicoLab/slmcode/pkg/harness"
1616
"github.com/UnicoLab/slmcode/pkg/orchestrator"
17+
"github.com/UnicoLab/slmcode/pkg/plan"
18+
"github.com/UnicoLab/slmcode/pkg/rewind"
1719
"github.com/UnicoLab/slmcode/pkg/session"
1820
)
1921

@@ -50,6 +52,11 @@ func runPremiumTUI() error {
5052
sess := cli.NewLiveSession()
5153
sess.SetState(loadDashboardFromHarness(h))
5254
sess.SetCompact(h.Config.CompactMode)
55+
sess.OnBoardRefresh(func() *plan.Board {
56+
_ = h.Orchestrator.Board().Load()
57+
snap := h.Orchestrator.Board().Snapshot()
58+
return &snap
59+
})
5360

5461
var runMu sync.Mutex
5562
var cancelRun func()
@@ -186,6 +193,18 @@ func runPremiumTUI() error {
186193
}
187194
return false, nil
188195
case "/compact":
196+
if arg == "context" || arg == "ctx" {
197+
res, err := h.Orchestrator.CompactContextNow()
198+
if err != nil {
199+
return false, err
200+
}
201+
if res.Compacted {
202+
fmt.Println(cli.Success(fmt.Sprintf("CONTEXT compacted %d→%d bytes", res.BeforeBytes, res.AfterBytes)))
203+
} else {
204+
fmt.Println(cli.Dim(fmt.Sprintf("CONTEXT already lean (%d bytes)", res.BeforeBytes)))
205+
}
206+
return false, nil
207+
}
189208
on := !sess.Compact()
190209
if arg == "on" || arg == "1" || arg == "true" {
191210
on = true
@@ -197,10 +216,36 @@ func runPremiumTUI() error {
197216
h.Config.CompactMode = on
198217
_ = h.Config.Save()
199218
if on {
200-
fmt.Println(cli.Success("compact mode on"))
219+
fmt.Println(cli.Success("compact stream on — /compact context to summarize CONTEXT.md"))
201220
} else {
202-
fmt.Println(cli.Success("compact mode off"))
221+
fmt.Println(cli.Success("compact stream off"))
222+
}
223+
return false, nil
224+
case "/rewind":
225+
mgr := &rewind.Manager{SlmDir: h.Config.SlmDir(), Root: h.Config.Root}
226+
if arg == "" || arg == "list" {
227+
list, err := mgr.List()
228+
if err != nil {
229+
return false, err
230+
}
231+
if len(list) == 0 {
232+
fmt.Println(cli.Dim("no wave snapshots yet"))
233+
return false, nil
234+
}
235+
for i, s := range list {
236+
if i >= 10 {
237+
break
238+
}
239+
fmt.Printf(" %s wave=%d files=%d %s\n", s.ID, s.Wave, len(s.Files), s.CreatedAt)
240+
}
241+
fmt.Println(cli.Dim("usage: /rewind <snapshot-id>"))
242+
return false, nil
203243
}
244+
n, err := mgr.Restore(arg)
245+
if err != nil {
246+
return false, err
247+
}
248+
fmt.Println(cli.Success(fmt.Sprintf("restored %d files from %s", n, arg)))
204249
return false, nil
205250
case "/stats":
206251
head := sess.LatencyHead()
@@ -306,7 +351,7 @@ func handleTUIAgentCmd(h *harness.Harness, sess *cli.LiveSession, line string) e
306351
fmt.Println(cli.Dim(" Fields: title description provider model endpoint skills tools max_iter max_tokens temperature system_prompt"))
307352
return nil
308353
case "show":
309-
a := cli.FindPublicAgent(custom, cmd.ID)
354+
a := agents.AgentDetail(cmd.ID, custom)
310355
if a == nil {
311356
return fmt.Errorf("agent %q not found", cmd.ID)
312357
}
@@ -331,12 +376,15 @@ func handleTUIAgentCmd(h *harness.Harness, sess *cli.LiveSession, line string) e
331376
} else if got, rerr := agents.ReadCustomFile(filepath.Join(h.Config.AgentsDir(), cmd.ID+".yml")); rerr == nil {
332377
base = got
333378
} else {
334-
// Seed from builtin public view when overriding.
335-
if pub := cli.FindPublicAgent(custom, cmd.ID); pub != nil {
379+
// Seed from full builtin detail (includes system prompt).
380+
if pub := agents.AgentDetail(cmd.ID, custom); pub != nil {
336381
base.ID = cmd.ID
337382
if t, _ := pub["title"].(string); t != "" {
338383
base.Title = t
339384
}
385+
if d, _ := pub["description"].(string); d != "" {
386+
base.Description = d
387+
}
340388
if sp, _ := pub["system_prompt"].(string); sp != "" {
341389
base.SystemPrompt = sp
342390
}

0 commit comments

Comments
 (0)