@duckcodeailabs/dql-cli 1.2.0 → 1.3.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 (38) hide show
  1. package/dist/assets/dql-notebook/assets/index-B06pd_fZ.js +793 -0
  2. package/dist/assets/dql-notebook/assets/index-C_x4yXmA.css +1 -0
  3. package/dist/assets/dql-notebook/index.html +3 -3
  4. package/dist/commands/init.js +1 -1
  5. package/dist/commands/init.js.map +1 -1
  6. package/dist/commands/schedule.d.ts.map +1 -1
  7. package/dist/commands/schedule.js +89 -6
  8. package/dist/commands/schedule.js.map +1 -1
  9. package/dist/llm/index.d.ts +1 -1
  10. package/dist/llm/index.d.ts.map +1 -1
  11. package/dist/llm/index.js +8 -2
  12. package/dist/llm/index.js.map +1 -1
  13. package/dist/llm/providers/claude-agent-sdk.d.ts +3 -0
  14. package/dist/llm/providers/claude-agent-sdk.d.ts.map +1 -0
  15. package/dist/llm/{claude-agent-sdk.js → providers/claude-agent-sdk.js} +1 -1
  16. package/dist/llm/providers/claude-agent-sdk.js.map +1 -0
  17. package/dist/llm/{claude-code.d.ts → providers/claude-code.d.ts} +1 -1
  18. package/dist/llm/providers/claude-code.d.ts.map +1 -0
  19. package/dist/llm/providers/claude-code.js.map +1 -0
  20. package/dist/llm/types.d.ts +6 -0
  21. package/dist/llm/types.d.ts.map +1 -1
  22. package/dist/local-runtime.d.ts.map +1 -1
  23. package/dist/local-runtime.js +105 -2
  24. package/dist/local-runtime.js.map +1 -1
  25. package/dist/schedule/notifiers/email.js +1 -1
  26. package/dist/schedule/notifiers/email.js.map +1 -1
  27. package/dist/schedule/runs.d.ts.map +1 -1
  28. package/dist/schedule/runs.js +3 -2
  29. package/dist/schedule/runs.js.map +1 -1
  30. package/package.json +8 -8
  31. package/dist/assets/dql-notebook/assets/index-BZV40eAE.css +0 -1
  32. package/dist/assets/dql-notebook/assets/index-Cscl1A2H.js +0 -628
  33. package/dist/llm/claude-agent-sdk.d.ts +0 -3
  34. package/dist/llm/claude-agent-sdk.d.ts.map +0 -1
  35. package/dist/llm/claude-agent-sdk.js.map +0 -1
  36. package/dist/llm/claude-code.d.ts.map +0 -1
  37. package/dist/llm/claude-code.js.map +0 -1
  38. /package/dist/llm/{claude-code.js → providers/claude-code.js} +0 -0
@@ -4,6 +4,7 @@ import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, wat
4
4
  import { dirname, extname, join, normalize, relative, resolve } from 'node:path';
5
5
  import { buildExecutionPlan, createWelcomeNotebook, deserializeNotebook, getConnectorFormSchemas, hasSemanticRefs, resolveSemanticRefs, } from '@duckcodeailabs/dql-notebook';
6
6
  import { loadSemanticLayerFromDir, resolveSemanticLayerAsync, Parser, buildLineageGraph, buildManifest, analyzeImpact, buildTrustChain, detectDomainFlows, getDomainTrustOverview, queryLineage, queryCompleteLineagePaths, LineageGraph, canonicalize, canonicalizeNotebook, diffDQL, diffNotebook, } from '@duckcodeailabs/dql-core';
7
+ import { load as loadYaml } from 'js-yaml';
7
8
  import { listBlockTemplates } from './block-templates.js';
8
9
  import { getRunner as getLLMRunner } from './llm/index.js';
9
10
  import { buildSemanticObjectDetail, buildSemanticTree, computeSyncDiff, loadSemanticImportManifest, performSemanticImport, previewSemanticImport, syncSemanticImport, } from './semantic-import.js';
@@ -305,8 +306,11 @@ export async function startLocalServer(opts) {
305
306
  res.end(serializeJSON(merged));
306
307
  }
307
308
  catch (error) {
308
- res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
309
- res.end(serializeJSON(scanDataFiles(projectRoot)));
309
+ const message = error instanceof Error ? error.message : String(error);
310
+ console.warn(`[dql] /api/schema introspection failed: ${message}`);
311
+ const fallback = scanDataFiles(projectRoot).map((f) => ({ ...f, source: 'file' }));
312
+ res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' });
313
+ res.end(serializeJSON({ error: message, fallback }));
310
314
  }
311
315
  return;
312
316
  }
@@ -426,6 +430,7 @@ export async function startLocalServer(opts) {
426
430
  const parsedTags = tagsMatch
427
431
  ? tagsMatch[1].split(',').map((tag) => tag.trim().replace(/^"|"$/g, '')).filter(Boolean)
428
432
  : [];
433
+ const llmMatch = /llmContext\s*=\s*"((?:[^"\\]|\\.)*)"/.exec(source);
429
434
  blocks.push({
430
435
  name: nameMatch?.[1] ?? entry.name.replace('.dql', ''),
431
436
  domain: domainMatch?.[1] ?? 'uncategorized',
@@ -435,6 +440,7 @@ export async function startLocalServer(opts) {
435
440
  path: relPath,
436
441
  lastModified: stat.mtime.toISOString(),
437
442
  description: descMatch?.[1] ?? '',
443
+ llmContext: llmMatch?.[1] ?? null,
438
444
  });
439
445
  }
440
446
  catch { /* skip unreadable files */ }
@@ -453,6 +459,58 @@ export async function startLocalServer(opts) {
453
459
  }
454
460
  return;
455
461
  }
462
+ // ── Apps (App artifact listing for notebook AppsPanel) ────────────────
463
+ if (req.method === 'GET' && path === '/api/apps') {
464
+ try {
465
+ const appsRoot = join(projectRoot, 'apps');
466
+ const apps = [];
467
+ const listFilesByExt = (dir, ext) => {
468
+ const out = [];
469
+ try {
470
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
471
+ const full = join(dir, entry.name);
472
+ if (entry.isDirectory()) {
473
+ out.push(...listFilesByExt(full, ext).map((n) => `${entry.name}/${n}`));
474
+ }
475
+ else if (entry.isFile() && entry.name.endsWith(ext)) {
476
+ out.push(entry.name);
477
+ }
478
+ }
479
+ }
480
+ catch { /* dir missing; return [] */ }
481
+ return out;
482
+ };
483
+ if (existsSync(appsRoot)) {
484
+ for (const entry of readdirSync(appsRoot, { withFileTypes: true })) {
485
+ if (!entry.isDirectory() || !entry.name.endsWith('.dql-app'))
486
+ continue;
487
+ const appDir = join(appsRoot, entry.name);
488
+ try {
489
+ const raw = readFileSync(join(appDir, 'app.yml'), 'utf-8');
490
+ const manifest = loadYaml(raw);
491
+ if (!manifest || !manifest.name || !manifest.domain)
492
+ continue;
493
+ apps.push({
494
+ path: relative(projectRoot, appDir),
495
+ manifest,
496
+ notebooks: listFilesByExt(join(appDir, 'notebooks'), '.dqlnb'),
497
+ dashboards: listFilesByExt(join(appDir, 'dashboards'), '.dql'),
498
+ hasDigest: existsSync(join(appDir, 'digest.dql')),
499
+ });
500
+ }
501
+ catch { /* skip unreadable apps */ }
502
+ }
503
+ }
504
+ apps.sort((a, b) => a.manifest.name.localeCompare(b.manifest.name));
505
+ res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
506
+ res.end(serializeJSON({ apps }));
507
+ }
508
+ catch (error) {
509
+ res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' });
510
+ res.end(serializeJSON({ error: error instanceof Error ? error.message : String(error) }));
511
+ }
512
+ return;
513
+ }
456
514
  // ── Block status update ──────────────────────────────────────────────
457
515
  if (req.method === 'POST' && path === '/api/blocks/status') {
458
516
  try {
@@ -516,6 +574,51 @@ export async function startLocalServer(opts) {
516
574
  }
517
575
  return;
518
576
  }
577
+ // ── Block body (re-read from disk, used by bound-cell refresh) ──────
578
+ if (req.method === 'GET' && path === '/api/blocks/body') {
579
+ try {
580
+ const blockPath = url.searchParams.get('path');
581
+ if (!blockPath) {
582
+ res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
583
+ res.end(serializeJSON({ error: 'path parameter is required' }));
584
+ return;
585
+ }
586
+ const absolutePath = resolve(projectRoot, blockPath);
587
+ if (!absolutePath.startsWith(projectRoot + '/') && absolutePath !== projectRoot) {
588
+ res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
589
+ res.end(serializeJSON({ error: 'path escapes project root' }));
590
+ return;
591
+ }
592
+ if (!existsSync(absolutePath)) {
593
+ res.writeHead(404, { 'Content-Type': 'application/json; charset=utf-8' });
594
+ res.end(serializeJSON({ error: 'block not found' }));
595
+ return;
596
+ }
597
+ const body = readFileSync(absolutePath, 'utf-8');
598
+ let commitSha = null;
599
+ try {
600
+ const { execSync } = await import('node:child_process');
601
+ const sha = execSync(`git log -1 --format=%H -- "${blockPath}"`, {
602
+ cwd: projectRoot,
603
+ encoding: 'utf-8',
604
+ stdio: ['ignore', 'pipe', 'ignore'],
605
+ timeout: 5000,
606
+ }).trim();
607
+ commitSha = sha.length > 0 ? sha : null;
608
+ }
609
+ catch {
610
+ commitSha = null;
611
+ }
612
+ res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
613
+ res.end(serializeJSON({ path: blockPath, body, commitSha }));
614
+ }
615
+ catch (error) {
616
+ const message = error instanceof Error ? error.message : String(error);
617
+ res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' });
618
+ res.end(serializeJSON({ error: message }));
619
+ }
620
+ return;
621
+ }
519
622
  // ── Run block tests ────────────────────────────────────────────────
520
623
  if (req.method === 'POST' && path === '/api/blocks/run-tests') {
521
624
  try {