@lmctl-ai/lmctl 0.1.0

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.
Files changed (29) hide show
  1. package/LICENSE +36 -0
  2. package/README.md +36 -0
  3. package/bin/lmctl +4 -0
  4. package/dist/cli/index.js +2180 -0
  5. package/dist/cli/schema.sql +660 -0
  6. package/dist/cli/side_effect_classifier.json +19 -0
  7. package/dist/config/ai_test_templates/example-test.md.template +50 -0
  8. package/dist/config/ai_test_templates/index.md.template +27 -0
  9. package/dist/config/durable_memory_templates/index.md.template +29 -0
  10. package/dist/config/durable_memory_templates/skills_general.md.template +42 -0
  11. package/dist/config/durable_memory_templates/skills_lmdebug.md.template +31 -0
  12. package/dist/config/durable_memory_templates/skills_lmprobe.md.template +31 -0
  13. package/package.json +42 -0
  14. package/workflows/bugfix-extended-v2.compound.json +1018 -0
  15. package/workflows/bugfix-v2.compound.json +856 -0
  16. package/workflows/claim-check-spike-v2.compound.json +136 -0
  17. package/workflows/document-creation.compound.json +200 -0
  18. package/workflows/durable-memory-consolidation-v2.compound.json +185 -0
  19. package/workflows/example-v2.compound.json +200 -0
  20. package/workflows/image-qa.compound.json +128 -0
  21. package/workflows/index.jsonl +15 -0
  22. package/workflows/info-qa.compound.json +120 -0
  23. package/workflows/newspaper.compound.json +129 -0
  24. package/workflows/pr-fix.compound.json +183 -0
  25. package/workflows/pr-followup-v2.compound.json +969 -0
  26. package/workflows/provider-probe.compound.json +107 -0
  27. package/workflows/qa-suite.compound.json +186 -0
  28. package/workflows/spec-driven-task.compound.json +460 -0
  29. package/workflows/triage-v2.compound.json +721 -0
@@ -0,0 +1,200 @@
1
+ {
2
+ "schema_version": "lmctl/v3",
3
+ "definition_schema_version": 3,
4
+ "name": "example-v2",
5
+ "version": 1,
6
+ "description": "Demonstrates a simple multi-step workflow with agent work and review for smoke testing and template examples.",
7
+ "estimated_duration_ms": 30000,
8
+ "errors": {
9
+ "on_unhandled_failure": {
10
+ "attention_kind": "workflow_failed",
11
+ "severity": "error",
12
+ "capture_evidence": true
13
+ }
14
+ },
15
+ "steps": [
16
+ {
17
+ "id": "s-research-c47b",
18
+ "name": "research",
19
+ "type": "lmctl/consolidate",
20
+ "typeVersion": 1,
21
+ "parameters": {
22
+ "research_artifact_prefix": "research"
23
+ },
24
+ "members": {
25
+ "researchers": [
26
+ {
27
+ "team": "default",
28
+ "alias": "Researcher",
29
+ "prompt_template": "Research the existing test patterns in the project at {{project.local_path}} and summarise your findings.",
30
+ "topic": "existing tests and test patterns"
31
+ },
32
+ {
33
+ "team": "default",
34
+ "alias": "Researcher2",
35
+ "prompt_template": "Summarise the bug described in: {{job_payload.description}}",
36
+ "topic": "bug description from job payload"
37
+ }
38
+ ],
39
+ "consolidator": {
40
+ "team": "default",
41
+ "alias": "Consolidator",
42
+ "prompt_template": "Given the research inputs below, produce a consolidated analysis plan. End with STANCE: ok"
43
+ }
44
+ }
45
+ },
46
+ {
47
+ "id": "s-code-review-dd5c",
48
+ "name": "code_review",
49
+ "type": "lmctl/review",
50
+ "typeVersion": 1,
51
+ "parameters": {
52
+ "pre_checks": [
53
+ {
54
+ "kind": "shell",
55
+ "command": "git -C {{project.local_path}} diff --quiet HEAD || true",
56
+ "description": "check repo accessible"
57
+ }
58
+ ],
59
+ "writes_to_project_path": true,
60
+ "max_loops": 3
61
+ },
62
+ "members": {
63
+ "coder": {
64
+ "team": "default",
65
+ "alias": "Coder",
66
+ "prompt_template": "Fix the bug described in {{job_payload.description}} in {{project.local_path}}. When done, respond with STANCE: done"
67
+ },
68
+ "reviewers": [
69
+ {
70
+ "team": "default",
71
+ "alias": "Reviewer",
72
+ "prompt_template": "Review the coder's work. If satisfactory respond STANCE: approve, otherwise respond STANCE: request_changes followed by feedback."
73
+ }
74
+ ]
75
+ }
76
+ },
77
+ {
78
+ "id": "s-interactive-handoff-7a4f",
79
+ "name": "interactive_handoff",
80
+ "type": "lmctl/interactive",
81
+ "typeVersion": 1,
82
+ "parameters": {
83
+ "termination": {
84
+ "operator_signal": true,
85
+ "agent_signal": "HANDOFF_COMPLETE",
86
+ "max_turns": 5
87
+ },
88
+ "artifact_name": "handoff_summary"
89
+ },
90
+ "members": {
91
+ "agent": {
92
+ "team": "default",
93
+ "alias": "Coder",
94
+ "initial_prompt_template": "The fix has been reviewed and approved. Please summarise the changes made to {{project.local_path}} for the operator. When you are done, include the text HANDOFF_COMPLETE in your response."
95
+ }
96
+ }
97
+ },
98
+ {
99
+ "id": "s-terminal-aborted-df78",
100
+ "name": "terminal:aborted",
101
+ "type": "lmctl/terminal",
102
+ "typeVersion": 1,
103
+ "parameters": {
104
+ "name": "aborted",
105
+ "kind": "failure"
106
+ }
107
+ },
108
+ {
109
+ "id": "s-terminal-done-bb66",
110
+ "name": "terminal:done",
111
+ "type": "lmctl/terminal",
112
+ "typeVersion": 1,
113
+ "parameters": {
114
+ "name": "done",
115
+ "kind": "success"
116
+ }
117
+ }
118
+ ],
119
+ "connections": {
120
+ "s-research-c47b": {
121
+ "ok": [
122
+ [
123
+ {
124
+ "step_id": "s-code-review-dd5c",
125
+ "type": "main",
126
+ "index": 0
127
+ }
128
+ ]
129
+ ],
130
+ "error": [
131
+ [
132
+ {
133
+ "step_id": "s-terminal-aborted-df78",
134
+ "type": "main",
135
+ "index": 0
136
+ }
137
+ ]
138
+ ]
139
+ },
140
+ "s-code-review-dd5c": {
141
+ "approve": [
142
+ [
143
+ {
144
+ "step_id": "s-interactive-handoff-7a4f",
145
+ "type": "main",
146
+ "index": 0
147
+ }
148
+ ]
149
+ ],
150
+ "request_changes": [
151
+ [
152
+ {
153
+ "step_id": "s-code-review-dd5c",
154
+ "type": "main",
155
+ "index": 0
156
+ }
157
+ ]
158
+ ],
159
+ "fail_pre_check": [
160
+ [
161
+ {
162
+ "step_id": "s-terminal-aborted-df78",
163
+ "type": "main",
164
+ "index": 0
165
+ }
166
+ ]
167
+ ],
168
+ "max_loops_exceeded": [
169
+ [
170
+ {
171
+ "step_id": "s-terminal-aborted-df78",
172
+ "type": "main",
173
+ "index": 0
174
+ }
175
+ ]
176
+ ]
177
+ },
178
+ "s-interactive-handoff-7a4f": {
179
+ "done": [
180
+ [
181
+ {
182
+ "step_id": "s-terminal-done-bb66",
183
+ "type": "main",
184
+ "index": 0
185
+ }
186
+ ]
187
+ ],
188
+ "timeout": [
189
+ [
190
+ {
191
+ "step_id": "s-terminal-aborted-df78",
192
+ "type": "main",
193
+ "index": 0
194
+ }
195
+ ]
196
+ ]
197
+ }
198
+ },
199
+ "entry_step_id": "s-research-c47b"
200
+ }
@@ -0,0 +1,128 @@
1
+ {
2
+ "schema_version": "lmctl/v3",
3
+ "definition_schema_version": 3,
4
+ "name": "image-qa",
5
+ "version": 1,
6
+ "description": "Reviews image or visual output against expected criteria and produces a QA verdict with evidence.",
7
+ "estimated_duration_ms": 90000,
8
+ "errors": {
9
+ "on_unhandled_failure": {
10
+ "attention_kind": "workflow_failed",
11
+ "severity": "error",
12
+ "capture_evidence": true
13
+ }
14
+ },
15
+ "inputs": [
16
+ {
17
+ "name": "image_path",
18
+ "type": "string",
19
+ "required": true,
20
+ "description": "Absolute path to the uploaded image or document."
21
+ },
22
+ {
23
+ "name": "prompt",
24
+ "type": "string",
25
+ "required": true,
26
+ "description": "Question or instruction for the image."
27
+ }
28
+ ],
29
+ "outputs": [
30
+ {
31
+ "name": "answer",
32
+ "type": "string",
33
+ "source_step_id": "image_qa:coder[0]",
34
+ "source_field": "image_qa:coder[0]_transcript",
35
+ "description": "Coder's markdown answer about the uploaded image."
36
+ }
37
+ ],
38
+ "steps": [
39
+ {
40
+ "id": "s-image-qa-4f9a",
41
+ "name": "image_qa",
42
+ "type": "lmctl/review",
43
+ "typeVersion": 1,
44
+ "estimated_duration_ms": 90000,
45
+ "parameters": {
46
+ "max_loops": 1
47
+ },
48
+ "members": {
49
+ "coder": {
50
+ "team": "default",
51
+ "alias": "Coder",
52
+ "prompt_template": "You are an agent answering a layman's question about an image or document they uploaded.\n\nImage path: ={{ context.inputs.image_path }}\nUser's question: ={{ context.inputs.prompt }}\n\nPlease read the file at the path above. Then answer the user's question with specific visual details. If it is a document, bill, or letter, transcribe the visible text you can read. Return your answer as markdown.\n\nEnd with exactly:\nSTANCE: ok\n\nIf you cannot read the file, explain the limitation and end with exactly:\nSTANCE: blocked"
53
+ },
54
+ "reviewers": []
55
+ }
56
+ },
57
+ {
58
+ "id": "s-terminal-done-a9c1",
59
+ "name": "terminal:done",
60
+ "type": "lmctl/terminal",
61
+ "typeVersion": 1,
62
+ "parameters": {
63
+ "name": "done",
64
+ "kind": "success"
65
+ }
66
+ },
67
+ {
68
+ "id": "s-terminal-aborted-b6e2",
69
+ "name": "terminal:aborted",
70
+ "type": "lmctl/terminal",
71
+ "typeVersion": 1,
72
+ "parameters": {
73
+ "name": "aborted",
74
+ "kind": "failure"
75
+ }
76
+ }
77
+ ],
78
+ "connections": {
79
+ "s-image-qa-4f9a": {
80
+ "approve": [
81
+ [
82
+ {
83
+ "step_id": "s-terminal-done-a9c1",
84
+ "type": "main",
85
+ "index": 0
86
+ }
87
+ ]
88
+ ],
89
+ "ok": [
90
+ [
91
+ {
92
+ "step_id": "s-terminal-done-a9c1",
93
+ "type": "main",
94
+ "index": 0
95
+ }
96
+ ]
97
+ ],
98
+ "blocked": [
99
+ [
100
+ {
101
+ "step_id": "s-terminal-aborted-b6e2",
102
+ "type": "main",
103
+ "index": 0
104
+ }
105
+ ]
106
+ ],
107
+ "aborted": [
108
+ [
109
+ {
110
+ "step_id": "s-terminal-aborted-b6e2",
111
+ "type": "main",
112
+ "index": 0
113
+ }
114
+ ]
115
+ ],
116
+ "rejected": [
117
+ [
118
+ {
119
+ "step_id": "s-terminal-aborted-b6e2",
120
+ "type": "main",
121
+ "index": 0
122
+ }
123
+ ]
124
+ ]
125
+ }
126
+ },
127
+ "entry_step_id": "s-image-qa-4f9a"
128
+ }
@@ -0,0 +1,15 @@
1
+ {"name":"bugfix-extended-v2","file":"bugfix-extended-v2.compound.json","description":"Investigates a bug report, develops a fix through coder and reviewer turns, verifies the result, and reports the final status."}
2
+ {"name":"bugfix-v2","file":"bugfix-v2.compound.json","description":"Takes a bug description, asks an agent to diagnose and fix it in the project, then verifies and reports the outcome."}
3
+ {"name":"claim-check-spike-v2","file":"claim-check-spike-v2.compound.json","description":"Explores whether project issue claiming and follow-up work queues behave correctly for a small spike workflow."}
4
+ {"name":"document-creation","file":"document-creation.compound.json","description":"Creates or revises a project document through agent drafting and review, then writes the accepted document to the project."}
5
+ {"name":"durable-memory-consolidation-v2","file":"durable-memory-consolidation-v2.compound.json","description":"Consolidates durable project memory from recent work so future sessions can recover important context quickly."}
6
+ {"name":"example-v2","file":"example-v2.compound.json","description":"Demonstrates a simple multi-step workflow with agent work and review for smoke testing and template examples."}
7
+ {"name":"image-qa","file":"image-qa.compound.json","description":"Reviews image or visual output against expected criteria and produces a QA verdict with evidence."}
8
+ {"name":"info-qa","file":"info-qa.compound.json","description":"Runs an information-oriented QA workflow that checks project facts, evidence, and expected outcomes without modifying the project."}
9
+ {"name":"newspaper","file":"newspaper.compound.json","description":"Builds a newspaper-style summary from project or external inputs, organizing findings into a readable generated artifact."}
10
+ {"name":"pr-fix","file":"pr-fix.compound.json","description":"Claims one project issue, reads the failing test chapter, fixes the project with coder/reviewer loop, commits, and closes the issue."}
11
+ {"name":"pr-followup-v2","file":"pr-followup-v2.compound.json","description":"Follows up on pull-request feedback, applies needed changes, verifies them, and reports whether the PR is ready."}
12
+ {"name":"provider-probe","file":"provider-probe.compound.json","description":"Checks whether configured AI providers and team members can respond successfully in the current environment."}
13
+ {"name":"qa-suite","file":"qa-suite.compound.json","description":"Runs project QA chapters, interprets failures, creates project issues for failing chapters, and reports the open issue count."}
14
+ {"name":"spec-driven-task","file":"spec-driven-task.compound.json","description":"Turns a written task specification into project changes through agent implementation, review, and verification."}
15
+ {"name":"triage-v2","file":"triage-v2.compound.json","description":"Triages incoming issues, filters duplicates or unclear reports, assesses fixability, and produces candidate work items."}
@@ -0,0 +1,120 @@
1
+ {
2
+ "schema_version": "lmctl/v3",
3
+ "definition_schema_version": 3,
4
+ "name": "info-qa",
5
+ "version": 1,
6
+ "description": "Runs an information-oriented QA workflow that checks project facts, evidence, and expected outcomes without modifying the project.",
7
+ "estimated_duration_ms": 90000,
8
+ "errors": {
9
+ "on_unhandled_failure": {
10
+ "attention_kind": "workflow_failed",
11
+ "severity": "error",
12
+ "capture_evidence": true
13
+ }
14
+ },
15
+ "inputs": [
16
+ {
17
+ "name": "question",
18
+ "type": "string",
19
+ "required": true,
20
+ "description": "Question to answer."
21
+ },
22
+ {
23
+ "name": "output_path",
24
+ "type": "string",
25
+ "required": false,
26
+ "description": "Optional markdown path for the consolidated answer."
27
+ }
28
+ ],
29
+ "outputs": [
30
+ {
31
+ "name": "answer",
32
+ "type": "string",
33
+ "source_step_id": "s-info-qa-7b4c",
34
+ "source_field": "consolidated_output",
35
+ "description": "Consolidated answer."
36
+ }
37
+ ],
38
+ "steps": [
39
+ {
40
+ "id": "s-info-qa-7b4c",
41
+ "name": "info_qa",
42
+ "type": "lmctl/consolidate",
43
+ "typeVersion": 1,
44
+ "estimated_duration_ms": 90000,
45
+ "parameters": {
46
+ "research_artifact_prefix": "info_qa"
47
+ },
48
+ "members": {
49
+ "researchers": [
50
+ {
51
+ "team": "default",
52
+ "alias": "ClaudeResearcher",
53
+ "topic": "Claude research perspective",
54
+ "prompt_template": "Research the question carefully and identify key facts, caveats, and source-quality concerns.\n\nQuestion: {{job_payload.question}}"
55
+ },
56
+ {
57
+ "team": "default",
58
+ "alias": "CodexResearcher",
59
+ "topic": "Codex research perspective",
60
+ "prompt_template": "Analyze the question from a second perspective. Focus on concrete evidence, contradictions, and what an operator should verify.\n\nQuestion: {{job_payload.question}}"
61
+ },
62
+ {
63
+ "team": "default",
64
+ "alias": "GeminiResearcher",
65
+ "topic": "Gemini research perspective",
66
+ "prompt_template": "Produce an independent answer draft with assumptions, uncertainty, and practical next steps.\n\nQuestion: {{job_payload.question}}"
67
+ }
68
+ ],
69
+ "consolidator": {
70
+ "team": "default",
71
+ "alias": "Consolidator",
72
+ "prompt_template": "Merge the research notes into one concise answer for a non-specialist. Keep claims grounded, identify uncertainty, and include next steps when useful.\n\nIf job_payload.output_path is set, write the final markdown answer there.\n\nEnd with exactly:\nSTANCE: ok"
73
+ }
74
+ }
75
+ },
76
+ {
77
+ "id": "s-terminal-done-f1a8",
78
+ "name": "terminal:done",
79
+ "type": "lmctl/terminal",
80
+ "typeVersion": 1,
81
+ "parameters": {
82
+ "name": "done",
83
+ "kind": "success"
84
+ }
85
+ },
86
+ {
87
+ "id": "s-terminal-aborted-3d2e",
88
+ "name": "terminal:aborted",
89
+ "type": "lmctl/terminal",
90
+ "typeVersion": 1,
91
+ "parameters": {
92
+ "name": "aborted",
93
+ "kind": "failure"
94
+ }
95
+ }
96
+ ],
97
+ "connections": {
98
+ "s-info-qa-7b4c": {
99
+ "ok": [
100
+ [
101
+ {
102
+ "step_id": "s-terminal-done-f1a8",
103
+ "type": "main",
104
+ "index": 0
105
+ }
106
+ ]
107
+ ],
108
+ "error": [
109
+ [
110
+ {
111
+ "step_id": "s-terminal-aborted-3d2e",
112
+ "type": "main",
113
+ "index": 0
114
+ }
115
+ ]
116
+ ]
117
+ }
118
+ },
119
+ "entry_step_id": "s-info-qa-7b4c"
120
+ }
@@ -0,0 +1,129 @@
1
+ {
2
+ "schema_version": "lmctl/v3",
3
+ "definition_schema_version": 3,
4
+ "name": "newspaper",
5
+ "version": 1,
6
+ "description": "Builds a newspaper-style summary from project or external inputs, organizing findings into a readable generated artifact.",
7
+ "estimated_duration_ms": 120000,
8
+ "errors": {
9
+ "on_unhandled_failure": {
10
+ "attention_kind": "workflow_failed",
11
+ "severity": "error",
12
+ "capture_evidence": true
13
+ }
14
+ },
15
+ "triggers": [
16
+ {
17
+ "id": "daily-digest",
18
+ "type": "lmctl/trigger-schedule",
19
+ "parameters": {
20
+ "cron": "0 6 * * *",
21
+ "timezone": "UTC"
22
+ }
23
+ }
24
+ ],
25
+ "inputs": [
26
+ {
27
+ "name": "topics",
28
+ "type": "array",
29
+ "required": true,
30
+ "description": "Topics to include in the digest."
31
+ },
32
+ {
33
+ "name": "output_dir",
34
+ "type": "string",
35
+ "required": false,
36
+ "description": "Optional output directory for digest markdown."
37
+ }
38
+ ],
39
+ "outputs": [
40
+ {
41
+ "name": "digest_md",
42
+ "type": "string",
43
+ "source_step_id": "s-gather-digest-4f0a",
44
+ "source_field": "consolidated_output",
45
+ "description": "Daily digest markdown."
46
+ }
47
+ ],
48
+ "steps": [
49
+ {
50
+ "id": "s-gather-digest-4f0a",
51
+ "name": "gather",
52
+ "type": "lmctl/consolidate",
53
+ "typeVersion": 1,
54
+ "parameters": {
55
+ "research_artifact_prefix": "newspaper"
56
+ },
57
+ "members": {
58
+ "researchers": [
59
+ {
60
+ "team": "default",
61
+ "alias": "Researcher1",
62
+ "topic": "Topic set A",
63
+ "prompt_template": "Research the first slice of the requested daily digest topics.\n\nTopics: {{job_payload.topics}}\nOutput directory: {{job_payload.output_dir}}"
64
+ },
65
+ {
66
+ "team": "default",
67
+ "alias": "Researcher2",
68
+ "topic": "Topic set B",
69
+ "prompt_template": "Research a second independent slice of the requested daily digest topics. Note contradictions and uncertainty.\n\nTopics: {{job_payload.topics}}\nOutput directory: {{job_payload.output_dir}}"
70
+ },
71
+ {
72
+ "team": "default",
73
+ "alias": "Researcher3",
74
+ "topic": "Topic set C",
75
+ "prompt_template": "Research a third independent slice of the requested daily digest topics. Prefer concise facts and source-quality notes.\n\nTopics: {{job_payload.topics}}\nOutput directory: {{job_payload.output_dir}}"
76
+ }
77
+ ],
78
+ "consolidator": {
79
+ "team": "default",
80
+ "alias": "Consolidator",
81
+ "prompt_template": "Merge the research into a readable daily newspaper-style markdown digest. Group by topic, keep it concise, and include caveats.\n\nIf job_payload.output_dir is set, write the digest markdown there.\n\nEnd with exactly:\nSTANCE: ok"
82
+ }
83
+ }
84
+ },
85
+ {
86
+ "id": "s-terminal-done-a615",
87
+ "name": "terminal:done",
88
+ "type": "lmctl/terminal",
89
+ "typeVersion": 1,
90
+ "parameters": {
91
+ "name": "done",
92
+ "kind": "success"
93
+ }
94
+ },
95
+ {
96
+ "id": "s-terminal-aborted-cc74",
97
+ "name": "terminal:aborted",
98
+ "type": "lmctl/terminal",
99
+ "typeVersion": 1,
100
+ "parameters": {
101
+ "name": "aborted",
102
+ "kind": "failure"
103
+ }
104
+ }
105
+ ],
106
+ "connections": {
107
+ "s-gather-digest-4f0a": {
108
+ "ok": [
109
+ [
110
+ {
111
+ "step_id": "s-terminal-done-a615",
112
+ "type": "main",
113
+ "index": 0
114
+ }
115
+ ]
116
+ ],
117
+ "error": [
118
+ [
119
+ {
120
+ "step_id": "s-terminal-aborted-cc74",
121
+ "type": "main",
122
+ "index": 0
123
+ }
124
+ ]
125
+ ]
126
+ }
127
+ },
128
+ "entry_step_id": "s-gather-digest-4f0a"
129
+ }