@dashai/cli 0.3.0 → 0.3.1

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.
package/dist/bin.js CHANGED
@@ -381,12 +381,7 @@ function manifestJson(opts) {
381
381
  },
382
382
  module_kind: kind,
383
383
  owns: {
384
- tables: [
385
- {
386
- slug: "items",
387
- fields: [{ slug: "title", type: "text", required: true }]
388
- }
389
- ]
384
+ tables: []
390
385
  }
391
386
  };
392
387
  if (kind === "custom") {
@@ -505,41 +500,42 @@ function gitignore() {
505
500
  ""
506
501
  ].join("\n");
507
502
  }
508
- function envLocalExample() {
503
+ function envLocalExample(apiUrl = SCAFFOLD_DEFAULT_API_URL) {
509
504
  return [
510
505
  "# Copy to .env.local + fill in real values.",
511
506
  "# These vars are auto-injected by `dashwise dev` (the unified dev loop)",
512
507
  "# from ~/.config/dashwise/auth.json \u2014 you only need to edit this file if",
513
508
  "# you want to point at a non-default backend or run `next dev` standalone.",
514
- "DASHWISE_API_URL=http://localhost:3000",
509
+ `DASHWISE_API_URL=${apiUrl}`,
515
510
  "# Client-side mirror \u2014 Next.js inlines NEXT_PUBLIC_* into the browser",
516
511
  "# bundle so the SDK's <AuthProvider> can hit `/api/auth/sessions/me`",
517
512
  "# on the right origin. Should match DASHWISE_API_URL above.",
518
- "NEXT_PUBLIC_DASHWISE_API_URL=http://localhost:3000",
513
+ `NEXT_PUBLIC_DASHWISE_API_URL=${apiUrl}`,
519
514
  "DASHWISE_API_TOKEN=",
520
515
  "DASHWISE_INSTALLATION_ID=local",
521
516
  ""
522
517
  ].join("\n");
523
518
  }
524
- function envLocal() {
519
+ function envLocal(apiUrl = SCAFFOLD_DEFAULT_API_URL) {
525
520
  return [
526
521
  "# Local dev config \u2014 auto-generated by `dashwise module init`.",
527
- "# Gitignored; safe to edit. `dashwise dev` (the unified loop) auto-",
528
- "# injects DASHWISE_API_TOKEN from ~/.config/dashwise/auth.json AND",
522
+ `# Backend URL pinned to your logged-in CLI config (${apiUrl}). Gitignored;`,
523
+ "# safe to edit. `dashwise dev` (the unified loop) auto-injects",
524
+ "# DASHWISE_API_TOKEN from ~/.config/dashwise/auth.json AND",
529
525
  "# DASHWISE_DEV_SESSION_ID from the dev session it registers \u2014 so",
530
526
  "# you typically don't need to set either here. Change DASHWISE_API_URL",
531
- "# (and NEXT_PUBLIC_DASHWISE_API_URL to match) to point at a non-default",
532
- "# backend (e.g. https://api.dashwise.net).",
527
+ "# (and NEXT_PUBLIC_DASHWISE_API_URL to match) to point at a different",
528
+ "# backend.",
533
529
  "#",
534
530
  "# DASHWISE_INSTALLATION_ID is only needed AFTER you publish + install",
535
531
  "# the module in a workspace; until then dev mode (DASHWISE_DEV_SESSION_ID,",
536
532
  "# auto-set by `dashwise dev`) is the auth path.",
537
- "DASHWISE_API_URL=http://localhost:3000",
533
+ `DASHWISE_API_URL=${apiUrl}`,
538
534
  "# Client-side mirror (must match DASHWISE_API_URL). Next.js inlines",
539
535
  "# NEXT_PUBLIC_* into the browser bundle so the SDK's AuthProvider can",
540
536
  "# call /api/auth/sessions/me on the right origin instead of bouncing",
541
537
  "# off the local module server with a 404.",
542
- "NEXT_PUBLIC_DASHWISE_API_URL=http://localhost:3000",
538
+ `NEXT_PUBLIC_DASHWISE_API_URL=${apiUrl}`,
543
539
  "DASHWISE_API_TOKEN=",
544
540
  "DASHWISE_INSTALLATION_ID=",
545
541
  ""
@@ -1513,8 +1509,227 @@ function escapeHtml(s) {
1513
1509
  function isValidSlug(slug) {
1514
1510
  return /^[a-z][a-z0-9_-]*$/.test(slug);
1515
1511
  }
1512
+ function claudeMd(opts) {
1513
+ const isCustom = (opts.kind ?? "hand_authored") === "custom";
1514
+ return `# CLAUDE.md \u2014 ${opts.name}
1515
+
1516
+ Instructions for AI coding agents (Claude Code, Cursor, etc.) working
1517
+ in this DashWise module. Read this before making changes.
1518
+
1519
+ ## What this module is
1520
+
1521
+ A DashWise ${isCustom ? "**custom Next.js** module (full app runtime, machine-class)" : "**hand-authored simple** module (isolate runtime)"} authored against \`@dashai/sdk\`.
1522
+ Module slug: \`${opts.slug}\`.
1523
+
1524
+ DashWise calls apps "modules". A module is a Next.js app + a
1525
+ manifest (\`module.json\`) declaring the tables it owns, modules it
1526
+ depends on, and actions it exposes. The DashWise backend hosts the
1527
+ data plane + auth; this module ships UI + business logic.
1528
+
1529
+ ## Spec-first, log-every-change
1530
+
1531
+ This scaffold mirrors the dashwise-backend convention:
1532
+
1533
+ - **\`spec.md\`** is the source of truth for what this module does \u2014
1534
+ tables, fields, API contracts, business rules, error cases. Update
1535
+ it BEFORE writing code that changes behavior. If a behavior isn't
1536
+ in \`spec.md\`, it isn't real yet.
1537
+ - **\`agent-log.md\`** is an append-only log of every meaningful
1538
+ change. Every commit that touches \`module.json\`, \`spec.md\`, a
1539
+ schema mutation, or a public surface MUST add an entry. Format:
1540
+
1541
+ \`\`\`
1542
+ ## YYYY-MM-DD HH:MM \u2014 <author or agent name>
1543
+
1544
+ **Change:** one-line summary
1545
+ **Files:** comma-separated list of files
1546
+ **Reason:** why this change was necessary
1547
+ **Spec impact:** none | updated spec.md \xA7<section>
1548
+ \`\`\`
1549
+
1550
+ Reverse chronological (newest first).
1551
+
1552
+ ## Schema changes go through the CLI, not by hand
1553
+
1554
+ \`module.json\` is the manifest. The backend has its own copy that
1555
+ the runtime data plane uses. To keep them in sync, mutate via the
1556
+ CLI \u2014 \`dashwise table create\`, \`dashwise field add\`, etc. \u2014
1557
+ which calls the schema endpoints and rewrites the local
1558
+ \`module.json\` from the backend's response. Hand-edits to
1559
+ \`module.json\` won't sync until the next CLI mutation picks them up.
1560
+
1561
+ Common commands:
1562
+
1563
+ \`\`\`
1564
+ dashwise table create <slug> --field <slug:type[:required]>
1565
+ dashwise table delete <slug>
1566
+ dashwise field add <table> <slug:type[:required]>
1567
+ dashwise field remove <table> <slug>
1568
+ dashwise field set-type <table> <slug> <type>
1569
+ \`\`\`
1570
+
1571
+ Allowed field types: \`text\`, \`long_text\`, \`number\`, \`boolean\`,
1572
+ \`date\`, \`datetime\`, \`single_select\`, \`multi_select\`,
1573
+ \`link_row\`, \`file\`, \`multi_file\`, \`email\`, \`url\`,
1574
+ \`phone\`, \`formula\`, \`ai\`.
1575
+
1576
+ ## Read + write data via the generated SDK
1577
+
1578
+ The CLI's watcher regenerates typed clients into
1579
+ \`node_modules/@dashai/generated/\` every time \`module.json\` changes.
1580
+ Import from there:
1581
+
1582
+ \`\`\`ts
1583
+ import { db, qb } from '@dashai/generated';
1584
+
1585
+ // Simple CRUD
1586
+ const rows = await db.<table>.list();
1587
+ await db.<table>.create({ /* fields */ });
1588
+
1589
+ // Query builder (joins, aggregates)
1590
+ const stats = await qb.from('<table>').where({ /* ... */ }).execute();
1591
+ \`\`\`
1592
+
1593
+ The data plane authenticates via the per-module runtime token cached
1594
+ in \`~/.config/dashwise/auth.json#modules[${opts.slug}]\` after
1595
+ \`dashwise init\` provisions the dev install. \`dashwise dev\` injects
1596
+ this token into the Next.js child env automatically.
1597
+
1598
+ ## Auth in dev mode
1599
+
1600
+ \`dashwise dev\` registers a dev-mode SSO session with the backend
1601
+ and injects \`DASHWISE_DEV_SESSION_ID\` so workspace members can sign
1602
+ into the locally-running module via DashWise SSO \u2014 no installed
1603
+ \`installation_id\` required.
1604
+
1605
+ In Server Components: \`await getServerSession()\` (from
1606
+ \`@dashai/sdk/auth/server\`).
1607
+ In Client Components: \`useSession()\` (from
1608
+ \`@dashai/sdk/auth/client\`), wrapped in \`<AuthProvider>\` (already
1609
+ in \`app/layout.tsx\`).
1610
+
1611
+ ## Local dev lifecycle
1612
+
1613
+ \`\`\`
1614
+ dashwise login # one-time, opens browser
1615
+ dashwise init [slug] # scaffold + provision dev install
1616
+ dashwise dev # watcher + next dev, auth env auto-injected
1617
+ dashwise module destroy-dev-install # tear down when done (cleans backend + auth.json)
1618
+ \`\`\`
1619
+
1620
+ ## Engineering bar
1621
+
1622
+ - **No hacks, shortcuts, or temporary "quick fixes" as final
1623
+ implementations.** If something needs work, leave it as a stub and
1624
+ open an issue / TODO with a clear name \u2014 don't bury a workaround.
1625
+ - **No silent error swallowing.** Catch what you can handle; surface
1626
+ what you can't. Tests should assert error codes, not just status.
1627
+ - **No untyped \`any\`.** The generated SDK gives you types \u2014 use
1628
+ them. If you need an escape hatch, add a \`@ts-expect-error\` with
1629
+ a comment explaining why.
1630
+ - **No secrets in code or env files.** Use \`runtime.secrets[]\` in
1631
+ \`module.json\`; values are encrypted at rest and resolved at
1632
+ runtime.
1633
+
1634
+ ## Pointers
1635
+
1636
+ - Full walkthrough \u2014 \`@dashai/cli\`'s [building-modules.md](https://github.com/Intuize/dashwise-cli/blob/main/docs/building-modules.md).
1637
+ - Manifest schema \u2014 \`@dashai/sdk/dist/manifest/schema.d.ts\` (generated from the backend Zod source of truth).
1638
+ - Query plane reference \u2014 same docs, \`Query AST v1 wire format\` section.
1639
+ `;
1640
+ }
1641
+ function specMd(opts) {
1642
+ return `# ${opts.name} \u2014 Spec
1643
+
1644
+ > Living document. Source of truth for what this module does. Update
1645
+ > this BEFORE changing code that changes behavior \u2014 see CLAUDE.md.
1646
+
1647
+ ## Notion
1648
+
1649
+ (link to ticket / design doc here, or remove this section)
1650
+
1651
+ ## Overview
1652
+
1653
+ One-sentence description of what this module does, who uses it, and
1654
+ what tables it owns.
1655
+
1656
+ ## Database schema
1657
+
1658
+ | Table | Columns | Notes |
1659
+ |---|---|---|
1660
+ | (none yet) | run \`dashwise table create <slug> --field <slug:type>\` to add one | |
1661
+
1662
+ ## API / contract
1663
+
1664
+ | Method | Path | Auth | Purpose |
1665
+ |---|---|---|---|
1666
+ | (none yet) | | | |
1667
+
1668
+ ## Business rules
1669
+
1670
+ - (RBAC, validation, domain logic.)
1671
+
1672
+ ## Dependencies
1673
+
1674
+ Modules this module reads from + which tables/actions:
1675
+
1676
+ - (none yet \u2014 declare in \`module.json#dependencies[]\`)
1677
+
1678
+ ## Exposed tables + actions
1679
+
1680
+ Tables or server-actions this module makes available to other
1681
+ modules:
1682
+
1683
+ - (none yet)
1684
+
1685
+ ## Error cases
1686
+
1687
+ - (what can go wrong + how it's handled)
1688
+
1689
+ ## Decisions
1690
+
1691
+ - (architectural choices + the trade-offs that drove them)
1692
+
1693
+ ## Open questions
1694
+
1695
+ - (anything blocking implementation)
1696
+ `;
1697
+ }
1698
+ function agentLogMd(opts) {
1699
+ return `# Agent Log \u2014 ${opts.name}
1700
+
1701
+ Append-only log of meaningful changes to this module. Every commit
1702
+ that touches \`module.json\`, \`spec.md\`, a schema, or a public
1703
+ surface MUST add an entry here in the same change.
1704
+
1705
+ Format (reverse chronological, newest first):
1706
+
1707
+ \`\`\`
1708
+ ## YYYY-MM-DD HH:MM \u2014 <author or agent name>
1709
+
1710
+ **Change:** one-line summary
1711
+ **Files:** comma-separated list of files
1712
+ **Reason:** why this change was necessary
1713
+ **Spec impact:** none | updated spec.md \xA7<section>
1714
+
1715
+ (optional: longer context, verification steps, decisions deferred)
1716
+ \`\`\`
1717
+
1718
+ ---
1719
+
1720
+ ## ${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)} \u2014 dashwise module init
1721
+
1722
+ **Change:** Scaffolded module \`${opts.slug}\` via \`dashwise module init\`.
1723
+ **Files:** entire scaffold (\`module.json\`, \`app/\`, \`components/\`, ...).
1724
+ **Reason:** initial scaffold.
1725
+ **Spec impact:** seeded \`spec.md\` template \u2014 fill in before first
1726
+ schema mutation.
1727
+ `;
1728
+ }
1729
+ var SCAFFOLD_DEFAULT_API_URL;
1516
1730
  var init_scaffold = __esm({
1517
1731
  "src/lib/scaffold.ts"() {
1732
+ SCAFFOLD_DEFAULT_API_URL = "http://localhost:3000";
1518
1733
  }
1519
1734
  });
1520
1735
  async function selectWorkspace(opts) {
@@ -1622,15 +1837,22 @@ async function moduleInitCommand(slugArg, options) {
1622
1837
  kind,
1623
1838
  ...options.git !== void 0 ? { repositoryUrl: options.git } : {}
1624
1839
  };
1840
+ const scaffoldApiUrl = resolveApiUrl();
1625
1841
  const files = [
1626
1842
  ["module.json", manifestJson(scaffoldOpts)],
1627
1843
  ["tsconfig.json", tsconfigJson()],
1628
1844
  ["next.config.mjs", nextConfig()],
1629
1845
  ["next-env.d.ts", nextEnvDts()],
1630
1846
  [".gitignore", gitignore()],
1631
- [".env.local.example", envLocalExample()],
1632
- [".env.local", envLocal()],
1633
- ["README.md", readme(scaffoldOpts)]
1847
+ [".env.local.example", envLocalExample(scaffoldApiUrl)],
1848
+ [".env.local", envLocal(scaffoldApiUrl)],
1849
+ ["README.md", readme(scaffoldOpts)],
1850
+ // HH-CC-FUP-5: agent-facing docs ship with every scaffold so AI
1851
+ // coding agents (Claude Code, Cursor, etc.) have the spec + log
1852
+ // discipline + SDK pointers loaded into context from byte one.
1853
+ ["CLAUDE.md", claudeMd(scaffoldOpts)],
1854
+ ["spec.md", specMd(scaffoldOpts)],
1855
+ ["agent-log.md", agentLogMd(scaffoldOpts)]
1634
1856
  ];
1635
1857
  if (kind === "custom") {
1636
1858
  files.push(
@@ -5722,7 +5944,7 @@ fieldCmd.command("set-type <table-slug> <field-slug> <new-type>").description(
5722
5944
  }
5723
5945
  })();
5724
5946
  function getVersion() {
5725
- return "0.3.0";
5947
+ return "0.3.1";
5726
5948
  }
5727
5949
  function parseIntOption(value) {
5728
5950
  const n = Number.parseInt(value, 10);