@noobdemon/noob-cli 1.10.20 → 1.11.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.
@@ -0,0 +1,238 @@
1
+ // Workflow read-only commands — chỉ in console, không đụng state/ask/tui.
2
+ // Tách ra khỏi repl.js để giảm kích thước file chính + dễ test riêng.
3
+ // workflowSave + maybeAskWorkflowDescription vẫn ở repl.js vì cần ask()/tui.
4
+
5
+ import { listWorkflows, loadWorkflow, deleteWorkflow, workflowsDir } from '../workflows.js';
6
+ import { getBuiltinWorkflow, listBuiltinWorkflows } from '../workflows-builtin.js';
7
+
8
+ // ── workflowBuiltins ───────────────────────────────────────────────────────
9
+ // compact=true → 1 dòng/workflow (dùng trong /workflow help). default → kèm description.
10
+ export function workflowBuiltins({ c, t, compact = false } = {}) {
11
+ const items = listBuiltinWorkflows();
12
+ if (!compact) {
13
+ console.log(
14
+ c.tool(
15
+ ' ' + (t.workflowBuiltinsTitle || `🎼 Workflow built-in (${items.length} mẫu ship sẵn):`)
16
+ )
17
+ );
18
+ } else {
19
+ console.log(c.accent(' Built-in workflow:'));
20
+ }
21
+ for (const w of items) {
22
+ console.log(' ' + c.accent('/workflow run ' + w.name) + c.dim(' · ' + w.pattern));
23
+ if (!compact) console.log(' ' + c.dim(w.description));
24
+ }
25
+ if (!compact) {
26
+ console.log('');
27
+ console.log(
28
+ c.dim(' Chạy: /workflow run <name> [input]. VD: /workflow run verify-claims README.md')
29
+ );
30
+ }
31
+ }
32
+
33
+ // ── workflowHelp ───────────────────────────────────────────────────────────
34
+ // Menu chính khi user gõ /workflow (rỗng) hoặc /workflow help.
35
+ export function workflowHelp({ c, t }) {
36
+ console.log(
37
+ c.tool(' ' + (t.workflowHelpTitle || '🎼 /workflow — orchestrate multi-agent workflow'))
38
+ );
39
+ console.log(
40
+ c.dim(
41
+ ' ' +
42
+ (t.workflowHelpSub ||
43
+ 'Workflow chia task lớn thành sub-agent chạy song song/độc lập → chống 3 failure mode của single-context: agentic laziness, self-preferential bias, goal drift.')
44
+ )
45
+ );
46
+ console.log('');
47
+ console.log(c.accent(' Cú pháp:'));
48
+ console.log(' /workflow <yêu cầu> chạy ad-hoc (model tự design workflow)');
49
+ console.log(' /workflow help | ? menu này');
50
+ console.log(' /workflow patterns 6 pattern workflow (theo article Thariq)');
51
+ console.log(' /workflow builtins 3 workflow built-in có sẵn');
52
+ console.log(' /workflow list workflow đã lưu');
53
+ console.log(' /workflow save <name> <req> lưu prompt template → ~/.noob/workflows/');
54
+ console.log(' /workflow load <name> xem nội dung (saved hoặc built-in)');
55
+ console.log(' /workflow run <name> [extra] chạy (built-in HOẶC saved, có thể thêm ngữ cảnh)');
56
+ console.log(' /workflow delete|rm <name> xoá workflow đã lưu');
57
+ console.log('');
58
+ console.log(c.accent(' Nhanh nhất để thử:'));
59
+ console.log(' ' + c.dim('/workflow builtins ') + 'xem có sẵn cái nào');
60
+ console.log(
61
+ ' ' + c.dim('/workflow run deep-research "async-await trong Python"') + ' chạy ngay'
62
+ );
63
+ console.log(
64
+ ' ' + c.dim('/workflow run verify-claims README.md ') + 'verify claim trong tài liệu'
65
+ );
66
+ console.log('');
67
+ console.log(
68
+ c.dim(
69
+ ' 💡 Repeatable workflow (triage, research, verify) — pair với /loop <interval> + /goal <text>'
70
+ )
71
+ );
72
+ console.log('');
73
+ workflowBuiltins({ c, t, compact: true });
74
+ }
75
+
76
+ // ── workflowPatterns ───────────────────────────────────────────────────────
77
+ // 6 pattern theo article Thariq. Mỗi pattern 1 dòng — user scan nhanh.
78
+ export function workflowPatterns({ c, t }) {
79
+ const PATTERNS = [
80
+ [
81
+ 'Classify-and-act',
82
+ 'classifier phân loại task → route tới sub-agent chuyên dụng. HOẶC classifier ở cuối để check output. Khi: input không đồng nhất, mỗi loại cần chiến lược khác.',
83
+ ],
84
+ [
85
+ 'Fan-out-and-synthesize',
86
+ 'task lớn chia N nhánh độc lập song song → gom kết quả. SYNTHESIZE STEP LÀ BARRIER (article L93): đợi tất cả fan-out xong mới merge. Khi: partition rõ theo file/module/khía cạnh.',
87
+ ],
88
+ [
89
+ 'Adversarial verification',
90
+ '1 agent LÀM, 1 agent KHÁC verify output chống rubric/criteria. Khi: claim cần verify, code rủi ro, quyết định khó đảo.',
91
+ ],
92
+ [
93
+ 'Generate-and-filter',
94
+ 'sinh nhiều phương án song song → 1 agent lọc theo rubric/verify → dedupe → trả về top. Khi: bài toán mở, cần đa dạng giải pháp đã verify.',
95
+ ],
96
+ [
97
+ 'Tournament',
98
+ "N agents CÙNG LÀM 1 task với approach khác nhau → judge pairwise cho tới khi có winner. Pairwise comparison reliable hơn absolute scoring. Khi: cần ranking/rubric, hoặc bài toán 'taste' (naming, design).",
99
+ ],
100
+ [
101
+ 'Loop-until-done',
102
+ 'sub-agent làm 1 vòng, parent check stop condition (no new findings / no more errors), chưa đạt → spawn lại. Khi: lượng work không biết trước, có metric đo được.',
103
+ ],
104
+ ];
105
+ console.log(
106
+ c.tool(
107
+ ' ' +
108
+ (t.workflowPatternsTitle ||
109
+ '🎼 6 pattern workflow (theo article Thariq — A harness for every task)')
110
+ )
111
+ );
112
+ PATTERNS.forEach(([name, desc], i) => {
113
+ console.log(' ' + c.accent(`${i + 1}. ${name}`));
114
+ console.log(' ' + c.dim(desc));
115
+ });
116
+ console.log('');
117
+ console.log(
118
+ c.dim(
119
+ ' Tổ hợp: 1 workflow có thể compose nhiều pattern (vd triage = classify-and-act + loop-until-done + quarantine).'
120
+ )
121
+ );
122
+ console.log(
123
+ c.dim(
124
+ ' Lưu ý (article L165-167): workflow KHÔNG cần cho mọi task — tốn nhiều token. Việc < vài file → tự làm.'
125
+ )
126
+ );
127
+ }
128
+
129
+ // ── workflowList ───────────────────────────────────────────────────────────
130
+ export function workflowList({ c, t }) {
131
+ const saved = listWorkflows();
132
+ const builtins = listBuiltinWorkflows();
133
+ // Luôn show cả 2 nhóm — built-in quan trọng vì user quên chúng có sẵn.
134
+ console.log(
135
+ c.tool(
136
+ ' ' +
137
+ (t.workflowListHeader
138
+ ? t.workflowListHeader(workflowsDir())
139
+ : `Workflow đã lưu (${workflowsDir()}):`)
140
+ )
141
+ );
142
+ if (saved.length) {
143
+ for (const it of saved) {
144
+ const desc = it.description ? c.dim(' — ' + it.description) : '';
145
+ const date = it.updated ? c.dim(' [' + it.updated.slice(0, 10) + ']') : '';
146
+ console.log(' ' + c.accent(it.name) + desc + date);
147
+ }
148
+ } else {
149
+ console.log(c.dim(' (chưa có — /workflow save <name> <yêu cầu> để tạo)'));
150
+ }
151
+ console.log('');
152
+ console.log(c.accent(' Built-in workflow (chạy ngay, không cần save):'));
153
+ for (const w of builtins) {
154
+ console.log(' ' + c.accent('/workflow run ' + w.name) + c.dim(' · ' + w.title));
155
+ }
156
+ console.log('');
157
+ console.log(
158
+ c.dim(' Dùng: /workflow <yêu cầu> hoặc /workflow run <name> [input] hoặc /workflow help')
159
+ );
160
+ }
161
+
162
+ // ── workflowLoad ───────────────────────────────────────────────────────────
163
+ export function workflowLoad(name, { c, t }) {
164
+ if (!name) {
165
+ return console.log(
166
+ c.err(' ' + (t.workflowLoadNeedName || 'Cách dùng: /workflow load <name>'))
167
+ );
168
+ }
169
+ // Check built-in trước — user có thể quên chúng có sẵn.
170
+ const builtin = getBuiltinWorkflow(name);
171
+ if (builtin) {
172
+ console.log(c.tool(' ' + `🎼 Built-in workflow '${builtin.name}' — ${builtin.title}`));
173
+ console.log(c.dim(' pattern: ' + builtin.pattern));
174
+ console.log(c.dim(' ' + builtin.description));
175
+ console.log('');
176
+ console.log(
177
+ c.dim(' ── prompt template (chạy bằng /workflow run ' + builtin.name + ' <input>) ──')
178
+ );
179
+ console.log(builtin.buildPrompt('<input>'));
180
+ return;
181
+ }
182
+ const r = loadWorkflow(name);
183
+ if (!r.ok) {
184
+ return console.log(
185
+ c.err(
186
+ ' ' +
187
+ (t.workflowLoadError
188
+ ? t.workflowLoadError(name, r.error)
189
+ : `Không nạp được workflow '${name}': ${r.error}`)
190
+ )
191
+ );
192
+ }
193
+ console.log(
194
+ c.tool(
195
+ ' ' +
196
+ (t.workflowLoadOk ? t.workflowLoadOk(r.name, r.path) : `Workflow '${r.name}' (${r.path}):`)
197
+ )
198
+ );
199
+ if (r.meta.description) console.log(c.dim(' ' + r.meta.description));
200
+ if (r.meta.updated) console.log(c.dim(' updated: ' + r.meta.updated));
201
+ console.log('');
202
+ console.log(r.prompt);
203
+ }
204
+
205
+ // ── workflowDelete ─────────────────────────────────────────────────────────
206
+ export function workflowDelete(name, { c, t }) {
207
+ if (!name) {
208
+ return console.log(
209
+ c.err(' ' + (t.workflowDeleteNeedName || 'Cách dùng: /workflow delete <name>'))
210
+ );
211
+ }
212
+ // Chỉ xoá saved — built-in không xoá được.
213
+ const builtin = getBuiltinWorkflow(name);
214
+ if (builtin) {
215
+ return console.log(
216
+ c.err(
217
+ ' ' +
218
+ (t.workflowDeleteBuiltIn
219
+ ? t.workflowDeleteBuiltIn(name)
220
+ : `'${name}' là built-in workflow, không xoá được.`)
221
+ )
222
+ );
223
+ }
224
+ const r = deleteWorkflow(name);
225
+ if (!r.ok) {
226
+ return console.log(
227
+ c.err(
228
+ ' ' +
229
+ (t.workflowDeleteError
230
+ ? t.workflowDeleteError(name, r.error)
231
+ : `Không xoá được workflow '${name}': ${r.error}`)
232
+ )
233
+ );
234
+ }
235
+ console.log(
236
+ c.tool(' ' + (t.workflowDeleteOk ? t.workflowDeleteOk(name) : `Đã xoá workflow '${name}'.`))
237
+ );
238
+ }