@meshxdata/fops 0.1.32 → 0.1.35

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/CHANGELOG.md +372 -0
  2. package/package.json +1 -2
  3. package/src/agent/llm.js +3 -3
  4. package/src/commands/lifecycle.js +16 -0
  5. package/src/plugins/bundled/fops-plugin-dai-ttyd/fops.plugin.json +6 -0
  6. package/src/plugins/bundled/fops-plugin-dai-ttyd/index.js +182 -0
  7. package/src/plugins/bundled/fops-plugin-dai-ttyd/lib/client.js +164 -0
  8. package/src/plugins/bundled/fops-plugin-dai-ttyd/package.json +1 -0
  9. package/src/plugins/bundled/fops-plugin-embeddings/index.js +3 -1
  10. package/src/plugins/bundled/fops-plugin-embeddings/lib/indexer.js +1 -1
  11. package/src/plugins/bundled/fops-plugin-file/demo/landscape.yaml +67 -0
  12. package/src/plugins/bundled/fops-plugin-file/demo/orders_bad.csv +6 -0
  13. package/src/plugins/bundled/fops-plugin-file/demo/orders_good.csv +7 -0
  14. package/src/plugins/bundled/fops-plugin-file/demo/orders_reference.csv +6 -0
  15. package/src/plugins/bundled/fops-plugin-file/demo/orders_renamed.aligned.csv +6 -0
  16. package/src/plugins/bundled/fops-plugin-file/demo/orders_renamed.csv +6 -0
  17. package/src/plugins/bundled/fops-plugin-file/demo/rules.json +8 -0
  18. package/src/plugins/bundled/fops-plugin-file/demo/run.sh +110 -0
  19. package/src/plugins/bundled/fops-plugin-file/index.js +140 -24
  20. package/src/plugins/bundled/fops-plugin-file/lib/embed-index.js +7 -0
  21. package/src/plugins/bundled/fops-plugin-file/lib/match.js +11 -4
  22. package/src/plugins/bundled/fops-plugin-foundation/index.js +1574 -101
  23. package/src/plugins/bundled/fops-plugin-foundation/lib/align.js +42 -4
  24. package/src/plugins/bundled/fops-plugin-foundation/lib/apply.js +83 -41
  25. package/src/plugins/bundled/fops-plugin-foundation/lib/stack-apply.js +4 -1
  26. package/src/plugins/bundled/fops-plugin-foundation-graphql/index.js +39 -1
  27. package/src/plugins/bundled/fops-plugin-foundation-graphql/lib/graphql/resolvers/data-object.js +9 -6
  28. package/src/plugins/bundled/fops-plugin-foundation-graphql/lib/graphql/resolvers/data-product.js +9 -6
  29. package/src/ui/tui/App.js +1 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,378 @@
2
2
 
3
3
  All notable changes to @meshxdata/fops (Foundation Operator CLI) are documented here.
4
4
 
5
+ ## [0.1.35] - 2026-03-05
6
+
7
+ - status bar fix and new plugin for ttyd (27dde1e)
8
+ - file demo and tray (1a3e704)
9
+ - electron app (59ad0bb)
10
+ - compose and fops file plugin (1cf0e81)
11
+ - bump (346ffc1)
12
+ - localhost replaced by 127.0.0.1 (82b9f30)
13
+ - .29 (587b0e1)
14
+ - improve up down and bootstrap script (b79ebaf)
15
+ - checksum (22c8086)
16
+ - checksum (96b434f)
17
+ - checksum (15ed3c0)
18
+ - checksum (8a6543a)
19
+ - bump embed trino linksg (8440504)
20
+ - bump data (765ffd9)
21
+ - bump (cb8b232)
22
+ - broken tests (c532229)
23
+ - release 0.1.18, preflight checks (d902249)
24
+ - fix compute display bug (d10f5d9)
25
+ - cleanup packer files (6330f18)
26
+ - plan mode (cb36a8a)
27
+ - bump to 0.1.16 - agent ui (41ac1a2)
28
+ - bump to 0.1.15 - agent ui (4ebe2e1)
29
+ - bump to 0.1.14 (6c3a7fa)
30
+ - bump to 0.1.13 (8db570f)
31
+ - release 0.1.12 (c1c79e5)
32
+ - bump (11aa3b0)
33
+ - git keep and bump tui (be1678e)
34
+ - skills, index, rrf, compacted context (100k > 10k) (7b2fffd)
35
+ - cloudflare and token consumption, graphs indexing (0ad9eec)
36
+ - bump storage default (22c83ba)
37
+ - storage fix (68a22a0)
38
+ - skills update (7f56500)
39
+ - v9 bump (3864446)
40
+ - bump (c95eedc)
41
+ - rrf (dbf8c95)
42
+ - feat: warning when running predictions (95e8c52)
43
+ - feat: support for local predictions (45cf26b)
44
+ - feat: wip support for predictions + mlflow (3457052)
45
+ - add Reciprocal Rank Fusion (RRF) to knowledge and skill retrieval (61549bc)
46
+ - validate CSV headers in compute_run readiness check (a8c7a43)
47
+ - fix corrupted Iceberg metadata: probe tables + force cleanup on re-apply (50578af)
48
+ - enforce: never use foundation_apply to fix broken products (2e049bf)
49
+ - update SKILL.md with complete tool reference for knowledge retrieval (30b1924)
50
+ - add storage read, input DP table probe, and compute_run improvements (34e6c4c)
51
+ - skills update (1220385)
52
+ - skills update (bb66958)
53
+ - some tui improvement andd tools apply overwrite (e90c35c)
54
+ - skills update (e9227a1)
55
+ - skills update (669c4b3)
56
+ - fix plugin pre-flight checks (f741743)
57
+ - increase agent context (6479aaa)
58
+ - skills and init sql fixes (5fce35e)
59
+ - checksum (3518b56)
60
+ - penging job limit (a139861)
61
+ - checksum (575d28c)
62
+ - bump (92049ba)
63
+ - fix bug per tab status (0a33657)
64
+ - fix bug per tab status (50457c6)
65
+ - checksumming (0ad842e)
66
+ - shot af mardkwon overlapping (51f63b9)
67
+ - add spark dockerfile for multiarch builds (95abbd1)
68
+ - fix plugin initialization (16b9782)
69
+ - split index.js (50902a2)
70
+ - cloudflare cidr (cc4e021)
71
+ - cloduflare restrictions (2f6ba2d)
72
+ - sequential start (86b496e)
73
+ - sequential start (4930fe1)
74
+ - sequential start (353f014)
75
+ - qa tests (2dc6a1a)
76
+ - bump sha for .85 (dc2edfe)
77
+ - preserve env on sudo (7831227)
78
+ - bump sha for .84 (6c052f9)
79
+ - non interactive for azure vms (0aa8a2f)
80
+ - keep .env if present (d072450)
81
+ - bump (7a8e732)
82
+ - ensure opa is on compose if not set (f4a5228)
83
+ - checksum bump (a2ccc20)
84
+ - netrc defensive checks (a0b0ccc)
85
+ - netrc defensive checks (ae37403)
86
+ - checksum (ec45d11)
87
+ - update sync and fix up (7f9af72)
88
+ - expand test for azure and add new per app tag support (388a168)
89
+ - checksum on update (44005fc)
90
+ - cleanup for later (15e5313)
91
+ - cleanup for later (11c9597)
92
+ - switch branch feature (822fecc)
93
+ - add pull (d1c19ab)
94
+ - Bump hono from 4.11.9 to 4.12.0 in /operator-cli (ad25144)
95
+ - tests (f180a9a)
96
+ - cleanup (39c49a3)
97
+ - registry (7b7126a)
98
+ - reconcile kafka (832d0db)
99
+ - gh login bug (025886c)
100
+ - cleanup (bb96cab)
101
+ - strip envs from process (2421180)
102
+ - force use of gh creds not tokens in envs var (fff7787)
103
+ - resolve import between npm installs and npm link (79522e1)
104
+ - fix gh scope and azure states (afd846c)
105
+ - refactoring (da50352)
106
+ - split fops repo (d447638)
107
+ - aks (b791f8f)
108
+ - refactor azure (67d3bad)
109
+ - wildcard (391f023)
110
+ - azure plugin (c074074)
111
+ - zap (d7e6e7f)
112
+ - fix knock (cf89c05)
113
+ - azure (4adec98)
114
+ - Bump tar from 7.5.7 to 7.5.9 in /operator-cli (e41e98e)
115
+ - azure stack index.js split (de12272)
116
+ - Bump ajv from 8.17.1 to 8.18.0 in /operator-cli (76da21f)
117
+ - packer (9665fbc)
118
+ - remove stack api (db0fd4d)
119
+ - packer cleanup (fe1bf14)
120
+ - force refresh token (3a3d7e2)
121
+ - provision shell (2ad505f)
122
+ - azure vm management (91dcb31)
123
+ - azure specific (2b0cca8)
124
+ - azure packer (12175b8)
125
+ - init hashed pwd (db8523c)
126
+ - packer (5b5c7c4)
127
+ - doctor for azure vm (ed524fa)
128
+ - packer and 1pwd (c6d053e)
129
+ - split big index.js (dc85a1b)
130
+ - kafka volume update (21815ec)
131
+ - fix openai azure tools confirmation and flow (0118cd1)
132
+ - nighly fixx, test fix (5e0d04f)
133
+ - open ai training (cdc494a)
134
+ - openai integration in azure (1ca1475)
135
+ - ci (672cea9)
136
+ - refresh ghcr creds (4220c48)
137
+ - cleaned up version (1a0074f)
138
+ - traefik on ghcr and templates (8e31a05)
139
+ - apply fcl (e78911f)
140
+ - demo landscape (dd205fe)
141
+ - smarter login and schema (1af514f)
142
+ - no down before up unless something broke (56b1132)
143
+ - dai, reconcile failed containers (12907fa)
144
+ - reconcile dead container (7da75e4)
145
+ - defensive around storage buckets dir (b98871d)
146
+ - defensive around storage buckets dir (e86e132)
147
+ - gear in for multiarch (bf3fa3e)
148
+ - up autofix (99c7f89)
149
+ - autofix stale containers on up (43c7d0f)
150
+ - shared sessions fix (5de1359)
151
+ - share sessions between ui and tui (8321391)
152
+ - fix chat view display details (e263996)
153
+ - fix chat view display details (9babdda)
154
+ - tui up fixes (86e9f17)
155
+ - fix commands init (442538b)
156
+ - enable k3s profile (b2dcfc8)
157
+ - test up till job creation (656d388)
158
+ - tui fixes (0599779)
159
+ - cleanup (27731f0)
160
+ - train (90bf559)
161
+ - training (f809bf6)
162
+ - training (ba2b836)
163
+ - training (6fc5267)
164
+ - training (4af8ac9)
165
+ - fix build script (bd82836)
166
+ - infra test (5b79815)
167
+ - infra test (3a0ac05)
168
+ - infra test (e5c67b5)
169
+ - tests (ae7b621)
170
+ - tests (c09ae6a)
171
+ - update tui (4784153)
172
+ - training (0a5a330)
173
+ - tui (df4dd4a)
174
+ - pkg builds (4dc9993)
175
+ - also source env for creds (9a17d8f)
176
+ - fcl support (e8a5743)
177
+ - fcl support (8d6b6cd)
178
+ - fcl support (cb76a4a)
179
+ - bump package (df2ee85)
180
+ - add iam mgmt (2d3c294)
181
+ - fix k3s (976ae77)
182
+ - fix trino, add storage plugin (75cb1f4)
183
+ - add project root as config (a2863c6)
184
+ - failure learnings (637ef5c)
185
+ - Apple signed binaries (63a610e)
186
+ - send build info to apple for notary service (300c220)
187
+ - migration failure fixes (c7f0b2f)
188
+
189
+ ## [0.1.34] - 2026-03-05
190
+
191
+ - electron app (59ad0bb)
192
+ - compose and fops file plugin (1cf0e81)
193
+ - bump (346ffc1)
194
+ - localhost replaced by 127.0.0.1 (82b9f30)
195
+ - .29 (587b0e1)
196
+ - improve up down and bootstrap script (b79ebaf)
197
+ - checksum (22c8086)
198
+ - checksum (96b434f)
199
+ - checksum (15ed3c0)
200
+ - checksum (8a6543a)
201
+ - bump embed trino linksg (8440504)
202
+ - bump data (765ffd9)
203
+ - bump (cb8b232)
204
+ - broken tests (c532229)
205
+ - release 0.1.18, preflight checks (d902249)
206
+ - fix compute display bug (d10f5d9)
207
+ - cleanup packer files (6330f18)
208
+ - plan mode (cb36a8a)
209
+ - bump to 0.1.16 - agent ui (41ac1a2)
210
+ - bump to 0.1.15 - agent ui (4ebe2e1)
211
+ - bump to 0.1.14 (6c3a7fa)
212
+ - bump to 0.1.13 (8db570f)
213
+ - release 0.1.12 (c1c79e5)
214
+ - bump (11aa3b0)
215
+ - git keep and bump tui (be1678e)
216
+ - skills, index, rrf, compacted context (100k > 10k) (7b2fffd)
217
+ - cloudflare and token consumption, graphs indexing (0ad9eec)
218
+ - bump storage default (22c83ba)
219
+ - storage fix (68a22a0)
220
+ - skills update (7f56500)
221
+ - v9 bump (3864446)
222
+ - bump (c95eedc)
223
+ - rrf (dbf8c95)
224
+ - feat: warning when running predictions (95e8c52)
225
+ - feat: support for local predictions (45cf26b)
226
+ - feat: wip support for predictions + mlflow (3457052)
227
+ - add Reciprocal Rank Fusion (RRF) to knowledge and skill retrieval (61549bc)
228
+ - validate CSV headers in compute_run readiness check (a8c7a43)
229
+ - fix corrupted Iceberg metadata: probe tables + force cleanup on re-apply (50578af)
230
+ - enforce: never use foundation_apply to fix broken products (2e049bf)
231
+ - update SKILL.md with complete tool reference for knowledge retrieval (30b1924)
232
+ - add storage read, input DP table probe, and compute_run improvements (34e6c4c)
233
+ - skills update (1220385)
234
+ - skills update (bb66958)
235
+ - some tui improvement andd tools apply overwrite (e90c35c)
236
+ - skills update (e9227a1)
237
+ - skills update (669c4b3)
238
+ - fix plugin pre-flight checks (f741743)
239
+ - increase agent context (6479aaa)
240
+ - skills and init sql fixes (5fce35e)
241
+ - checksum (3518b56)
242
+ - penging job limit (a139861)
243
+ - checksum (575d28c)
244
+ - bump (92049ba)
245
+ - fix bug per tab status (0a33657)
246
+ - fix bug per tab status (50457c6)
247
+ - checksumming (0ad842e)
248
+ - shot af mardkwon overlapping (51f63b9)
249
+ - add spark dockerfile for multiarch builds (95abbd1)
250
+ - fix plugin initialization (16b9782)
251
+ - split index.js (50902a2)
252
+ - cloudflare cidr (cc4e021)
253
+ - cloduflare restrictions (2f6ba2d)
254
+ - sequential start (86b496e)
255
+ - sequential start (4930fe1)
256
+ - sequential start (353f014)
257
+ - qa tests (2dc6a1a)
258
+ - bump sha for .85 (dc2edfe)
259
+ - preserve env on sudo (7831227)
260
+ - bump sha for .84 (6c052f9)
261
+ - non interactive for azure vms (0aa8a2f)
262
+ - keep .env if present (d072450)
263
+ - bump (7a8e732)
264
+ - ensure opa is on compose if not set (f4a5228)
265
+ - checksum bump (a2ccc20)
266
+ - netrc defensive checks (a0b0ccc)
267
+ - netrc defensive checks (ae37403)
268
+ - checksum (ec45d11)
269
+ - update sync and fix up (7f9af72)
270
+ - expand test for azure and add new per app tag support (388a168)
271
+ - checksum on update (44005fc)
272
+ - cleanup for later (15e5313)
273
+ - cleanup for later (11c9597)
274
+ - switch branch feature (822fecc)
275
+ - add pull (d1c19ab)
276
+ - Bump hono from 4.11.9 to 4.12.0 in /operator-cli (ad25144)
277
+ - tests (f180a9a)
278
+ - cleanup (39c49a3)
279
+ - registry (7b7126a)
280
+ - reconcile kafka (832d0db)
281
+ - gh login bug (025886c)
282
+ - cleanup (bb96cab)
283
+ - strip envs from process (2421180)
284
+ - force use of gh creds not tokens in envs var (fff7787)
285
+ - resolve import between npm installs and npm link (79522e1)
286
+ - fix gh scope and azure states (afd846c)
287
+ - refactoring (da50352)
288
+ - split fops repo (d447638)
289
+ - aks (b791f8f)
290
+ - refactor azure (67d3bad)
291
+ - wildcard (391f023)
292
+ - azure plugin (c074074)
293
+ - zap (d7e6e7f)
294
+ - fix knock (cf89c05)
295
+ - azure (4adec98)
296
+ - Bump tar from 7.5.7 to 7.5.9 in /operator-cli (e41e98e)
297
+ - azure stack index.js split (de12272)
298
+ - Bump ajv from 8.17.1 to 8.18.0 in /operator-cli (76da21f)
299
+ - packer (9665fbc)
300
+ - remove stack api (db0fd4d)
301
+ - packer cleanup (fe1bf14)
302
+ - force refresh token (3a3d7e2)
303
+ - provision shell (2ad505f)
304
+ - azure vm management (91dcb31)
305
+ - azure specific (2b0cca8)
306
+ - azure packer (12175b8)
307
+ - init hashed pwd (db8523c)
308
+ - packer (5b5c7c4)
309
+ - doctor for azure vm (ed524fa)
310
+ - packer and 1pwd (c6d053e)
311
+ - split big index.js (dc85a1b)
312
+ - kafka volume update (21815ec)
313
+ - fix openai azure tools confirmation and flow (0118cd1)
314
+ - nighly fixx, test fix (5e0d04f)
315
+ - open ai training (cdc494a)
316
+ - openai integration in azure (1ca1475)
317
+ - ci (672cea9)
318
+ - refresh ghcr creds (4220c48)
319
+ - cleaned up version (1a0074f)
320
+ - traefik on ghcr and templates (8e31a05)
321
+ - apply fcl (e78911f)
322
+ - demo landscape (dd205fe)
323
+ - smarter login and schema (1af514f)
324
+ - no down before up unless something broke (56b1132)
325
+ - dai, reconcile failed containers (12907fa)
326
+ - reconcile dead container (7da75e4)
327
+ - defensive around storage buckets dir (b98871d)
328
+ - defensive around storage buckets dir (e86e132)
329
+ - gear in for multiarch (bf3fa3e)
330
+ - up autofix (99c7f89)
331
+ - autofix stale containers on up (43c7d0f)
332
+ - shared sessions fix (5de1359)
333
+ - share sessions between ui and tui (8321391)
334
+ - fix chat view display details (e263996)
335
+ - fix chat view display details (9babdda)
336
+ - tui up fixes (86e9f17)
337
+ - fix commands init (442538b)
338
+ - enable k3s profile (b2dcfc8)
339
+ - test up till job creation (656d388)
340
+ - tui fixes (0599779)
341
+ - cleanup (27731f0)
342
+ - train (90bf559)
343
+ - training (f809bf6)
344
+ - training (ba2b836)
345
+ - training (6fc5267)
346
+ - training (4af8ac9)
347
+ - fix build script (bd82836)
348
+ - infra test (5b79815)
349
+ - infra test (3a0ac05)
350
+ - infra test (e5c67b5)
351
+ - tests (ae7b621)
352
+ - tests (c09ae6a)
353
+ - update tui (4784153)
354
+ - training (0a5a330)
355
+ - tui (df4dd4a)
356
+ - pkg builds (4dc9993)
357
+ - also source env for creds (9a17d8f)
358
+ - fcl support (e8a5743)
359
+ - fcl support (8d6b6cd)
360
+ - fcl support (cb76a4a)
361
+ - bump package (df2ee85)
362
+ - add iam mgmt (2d3c294)
363
+ - fix k3s (976ae77)
364
+ - fix trino, add storage plugin (75cb1f4)
365
+ - add project root as config (a2863c6)
366
+ - failure learnings (637ef5c)
367
+ - Apple signed binaries (63a610e)
368
+ - send build info to apple for notary service (300c220)
369
+ - migration failure fixes (c7f0b2f)
370
+ - release to wipe clean pg on duplicate key error (a38bf4d)
371
+ - small fix (a26a674)
372
+
373
+ # Changelog
374
+
375
+ All notable changes to @meshxdata/fops (Foundation Operator CLI) are documented here.
376
+
5
377
  ## [0.1.32] - 2026-03-04
6
378
 
7
379
  - electron app (59ad0bb)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meshxdata/fops",
3
- "version": "0.1.32",
3
+ "version": "0.1.35",
4
4
  "description": "CLI to install and manage data mesh platforms",
5
5
  "keywords": [
6
6
  "fops",
@@ -46,7 +46,6 @@
46
46
  "chalk": "^5.3.0",
47
47
  "commander": "^12.0.0",
48
48
  "dataloader": "^2.2.3",
49
- "electron": "^34.5.8",
50
49
  "execa": "^9.5.2",
51
50
  "graphql": "^16.13.0",
52
51
  "hcl2-parser": "^1.0.3",
package/src/agent/llm.js CHANGED
@@ -559,11 +559,11 @@ function resolveProvider(opts, { anthropicKey, openaiKey, azureConfig, useClaude
559
559
  */
560
560
  function defaultModelForProvider(provider, opts, { anthropicKey, azureConfig }) {
561
561
  if (opts.model) return opts.model;
562
- if (provider === "anthropic" || provider === "claude_code") return process.env.ANTHROPIC_MODEL?.trim() || "claude-opus-4-20250514";
562
+ if (provider === "anthropic" || provider === "claude_code") return process.env.ANTHROPIC_MODEL?.trim() || "claude-sonnet-4-6";
563
563
  if (provider === "azure") return azureConfig?.deployment || "gpt-4o";
564
564
  if (provider === "openai") return process.env.OPENAI_MODEL?.trim() || "gpt-5";
565
565
  // Fallback
566
- return anthropicKey ? (process.env.ANTHROPIC_MODEL?.trim() || "claude-opus-4-20250514") : azureConfig ? azureConfig.deployment : "gpt-5";
566
+ return anthropicKey ? (process.env.ANTHROPIC_MODEL?.trim() || "claude-sonnet-4-6") : azureConfig ? azureConfig.deployment : "gpt-5";
567
567
  }
568
568
 
569
569
  export async function streamAssistantReply(root, messages, systemContent, opts) {
@@ -794,7 +794,7 @@ export async function callClaudeWithTools(messages, systemContent, tools, opts =
794
794
  const cached = getAnthropicModule();
795
795
  const { default: Anthropic } = cached || await import("@anthropic-ai/sdk");
796
796
  const client = new Anthropic({ apiKey: anthropicKey });
797
- const model = opts.model || process.env.ANTHROPIC_MODEL?.trim() || "claude-opus-4-20250514";
797
+ const model = opts.model || process.env.ANTHROPIC_MODEL?.trim() || "claude-sonnet-4-6";
798
798
  const claudeTools = toClaudeTools(tools);
799
799
 
800
800
  // Redact PII from context before sending
@@ -1316,6 +1316,11 @@ async function runUp(program, registry, opts) {
1316
1316
  const hasTraefik = profileArgs.includes("traefik");
1317
1317
  const needsSequentialUp = hasK3s && hasTraefik && !componentOnlyUp;
1318
1318
 
1319
+ // Stop the outer pre-flight spinner before runUpInner starts its own ticker.
1320
+ // Without this, two setInterval calls both write \r\x1b[K to stderr simultaneously,
1321
+ // causing the status line to flicker between the outer and inner spinner text.
1322
+ clearSpinner();
1323
+
1319
1324
  let result;
1320
1325
  if (componentOnlyUp) {
1321
1326
  const serviceList = opts.frontendDev && opts.component === "frontend"
@@ -1521,6 +1526,17 @@ async function runUp(program, registry, opts) {
1521
1526
  console.log(chalk.dim(`\n Foundation is running at ${browseUrl}`));
1522
1527
  console.log(chalk.dim(" Run `fops agent` to start the AI assistant.\n"));
1523
1528
  }
1529
+
1530
+ // Launch the system tray (macOS menu bar or Windows taskbar, full-stack up only)
1531
+ if ((process.platform === "darwin" || process.platform === "win32") && !opts.component) {
1532
+ const { spawn } = await import("node:child_process");
1533
+ const tray = spawn(process.argv[0], [process.argv[1], "foundation", "tray"], {
1534
+ stdio: "ignore",
1535
+ detached: true,
1536
+ env: { ...process.env },
1537
+ });
1538
+ tray.unref();
1539
+ }
1524
1540
  }
1525
1541
 
1526
1542
  // ── Restart backend after grant-admin ────────────────────────────────────────
@@ -0,0 +1,6 @@
1
+ {
2
+ "id": "fops-plugin-dai-ttyd",
3
+ "name": "DAI Talk-to-your-Data",
4
+ "version": "0.1.0",
5
+ "description": "Natural language queries against the DAI TTYD (Talk-to-your-Data) service"
6
+ }
@@ -0,0 +1,182 @@
1
+ import chalk from "chalk";
2
+ import { DaiTTYDClient } from "./lib/client.js";
3
+
4
+ const DIM = chalk.dim;
5
+ const OK = chalk.green;
6
+ const ERR = chalk.red;
7
+ const ACCENT = chalk.cyan;
8
+ const BOLD = chalk.bold;
9
+ const WARN = chalk.yellow;
10
+
11
+ export function register(api) {
12
+ const client = new DaiTTYDClient(api.config);
13
+
14
+ function clientFor({ url, jwt } = {}) {
15
+ if (!url && !jwt) return client;
16
+ return new DaiTTYDClient({
17
+ ...api.config,
18
+ ...(url && { baseUrl: url }),
19
+ ...(jwt && { authToken: jwt }),
20
+ });
21
+ }
22
+
23
+ // ─── Doctor check ────────────────────────────────────────────────────────
24
+ api.registerDoctorCheck({
25
+ name: "dai-ttyd: auth token",
26
+ fn: async () => {
27
+ const token =
28
+ api.config?.authToken?.trim() || process.env.DAI_AUTH_TOKEN?.trim();
29
+ if (!token) {
30
+ return {
31
+ ok: false,
32
+ message: "DAI_AUTH_TOKEN not set — configure via env or ~/.fops.json plugins.entries.fops-plugin-dai-ttyd.config.authToken",
33
+ };
34
+ }
35
+ return { ok: true, message: "DAI_AUTH_TOKEN is set" };
36
+ },
37
+ });
38
+
39
+ // ─── Agent tools ─────────────────────────────────────────────────────────
40
+
41
+ api.registerTool({
42
+ name: "ttyd_thread_create",
43
+ description: "Create a new TTYD conversation thread. Returns a thread_id to use with ttyd_ask.",
44
+ inputSchema: {
45
+ type: "object",
46
+ properties: {
47
+ title: { type: "string", description: "Optional title for the thread" },
48
+ },
49
+ },
50
+ async execute({ title } = {}) {
51
+ const threadId = await client.createThread(title || "fops session");
52
+ return JSON.stringify({ thread_id: threadId });
53
+ },
54
+ });
55
+
56
+ api.registerTool({
57
+ name: "ttyd_ask",
58
+ description:
59
+ "Ask a natural-language question to the DAI Talk-to-your-Data service. " +
60
+ "Returns the generated SQL and a text summary/answer. " +
61
+ "Optionally scoped to a dashboard or tile for context. " +
62
+ "If thread_id is omitted, a new thread is created automatically.",
63
+ inputSchema: {
64
+ type: "object",
65
+ properties: {
66
+ question: { type: "string", description: "The natural-language question to ask" },
67
+ thread_id: { type: "number", description: "Existing thread id for multi-turn conversations" },
68
+ dashboard_id: { type: "number", description: "Optional dashboard id for context" },
69
+ tile_id: { type: "number", description: "Optional tile id for context" },
70
+ },
71
+ required: ["question"],
72
+ },
73
+ async execute({ question, thread_id, dashboard_id, tile_id }) {
74
+ const result = await client.ask(question, {
75
+ threadId: thread_id,
76
+ dashboardId: dashboard_id,
77
+ tileId: tile_id,
78
+ });
79
+ return JSON.stringify(result);
80
+ },
81
+ });
82
+
83
+ // ─── CLI commands ─────────────────────────────────────────────────────────
84
+
85
+ api.registerCommand((program) => {
86
+ const ttyd = program
87
+ .command("ttyd")
88
+ .description("Talk-to-your-Data — query data with natural language")
89
+ .option("--url <url>", "Override the TTYD base URL (e.g. https://api-live.dashboards.ai)")
90
+ .option("--jwt <token>", "Bearer token (overrides DAI_AUTH_TOKEN env)");
91
+
92
+ // fops ttyd ask "<question>"
93
+ ttyd
94
+ .command("ask <question>")
95
+ .description("Ask a natural-language question and stream the answer")
96
+ .option("--thread <id>", "Reuse an existing thread id (for follow-up questions)", (v) => Number(v))
97
+ .option("--dashboard <id>", "Scope to a dashboard id", (v) => Number(v))
98
+ .option("--tile <id>", "Scope to a tile id", (v) => Number(v))
99
+ .option("--json", "Output raw JSON instead of formatted text")
100
+ .option("--debug", "Print raw SSE events")
101
+ .action(async (question, opts) => {
102
+ const { url, jwt } = ttyd.opts();
103
+ const c = clientFor({ url, jwt });
104
+
105
+ let threadId = opts.thread ?? null;
106
+ if (threadId == null) {
107
+ process.stdout.write(DIM(" Creating thread... "));
108
+ try {
109
+ threadId = await c.createThread();
110
+ process.stdout.write(DIM(`thread ${threadId}\n`));
111
+ } catch (e) {
112
+ process.stdout.write(WARN(`skipped (${e.message})\n`));
113
+ // Proceed without a thread_id — server may create one implicitly
114
+ }
115
+ }
116
+
117
+ console.log(ACCENT(`\n ── Asking ${"─".repeat(44)}`));
118
+ console.log(DIM(` ${question}\n`));
119
+
120
+ let sql = "";
121
+ const summaryParts = [];
122
+
123
+ try {
124
+ for await (const event of c.askStream(question, threadId, {
125
+ dashboardId: opts.dashboard,
126
+ tileId: opts.tile,
127
+ })) {
128
+ if (opts.debug) console.error(DIM(`[sse] ${JSON.stringify(event)}`));
129
+ if (event.type === "sql") {
130
+ sql = event.content ?? "";
131
+ if (!opts.json) {
132
+ console.log(BOLD(" SQL:"));
133
+ for (const line of sql.split("\n")) {
134
+ console.log(DIM(` ${line}`));
135
+ }
136
+ console.log();
137
+ }
138
+ } else if (event.type === "answer") {
139
+ const chunk = event.content ?? "";
140
+ summaryParts.push(chunk);
141
+ if (!opts.json) process.stdout.write(chunk);
142
+ } else if (event.type === "error") {
143
+ throw new Error(event.message ?? "TTYD error");
144
+ } else if (event.type === "done") {
145
+ break;
146
+ }
147
+ }
148
+ } catch (e) {
149
+ console.error(ERR(`\n ✗ ${e.message}`));
150
+ return;
151
+ }
152
+
153
+ if (!opts.json) {
154
+ if (summaryParts.length > 0) process.stdout.write("\n");
155
+ if (threadId != null) {
156
+ console.log(DIM(`\n thread: ${threadId}`));
157
+ console.log(DIM(" Use --thread to continue this conversation.\n"));
158
+ } else {
159
+ console.log();
160
+ }
161
+ } else {
162
+ console.log(JSON.stringify({ thread_id: threadId, sql, summary: summaryParts.join("") }, null, 2));
163
+ }
164
+ });
165
+
166
+ // fops ttyd thread new [title]
167
+ const thread = ttyd
168
+ .command("thread")
169
+ .description("Manage TTYD threads");
170
+
171
+ thread
172
+ .command("new [title]")
173
+ .description("Create a new conversation thread")
174
+ .action(async (title = "fops session") => {
175
+ const { url, jwt } = ttyd.opts();
176
+ const c = clientFor({ url, jwt });
177
+ const threadId = await c.createThread(title);
178
+ console.log(OK(` ✓ Thread created: ${threadId}`));
179
+ console.log(DIM(` Use: fops ttyd ask --thread ${threadId} "<question>"\n`));
180
+ });
181
+ });
182
+ }