@tanqory/dev-mcp 0.0.0-stage → 0.1.0-alpha.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.
Files changed (65) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +94 -2
  3. package/bin/tanqory-dev-mcp.mjs +16 -0
  4. package/bundled/examples/blank/config/settings.json +3 -0
  5. package/bundled/examples/blank/locales/en.json +22 -0
  6. package/bundled/examples/blank/locales/th.json +22 -0
  7. package/bundled/examples/blank/regions/footer.json +35 -0
  8. package/bundled/examples/blank/regions/header.json +13 -0
  9. package/bundled/examples/blank/src/bundle.ts +15 -0
  10. package/bundled/examples/blank/src/components/parts.tsx +32 -0
  11. package/bundled/examples/blank/src/entry.client.tsx +6 -0
  12. package/bundled/examples/blank/src/entry.server.tsx +13 -0
  13. package/bundled/examples/blank/src/sections/chrome.tsx +132 -0
  14. package/bundled/examples/blank/src/sections/commerce.tsx +242 -0
  15. package/bundled/examples/blank/src/sections/content.tsx +111 -0
  16. package/bundled/examples/blank/src/sections/editorial.tsx +107 -0
  17. package/bundled/examples/blank/src/settings.ts +15 -0
  18. package/bundled/examples/blank/src/styles/theme.css +195 -0
  19. package/bundled/examples/blank/src/templates.ts +14 -0
  20. package/bundled/examples/blank/src/theme.tsx +76 -0
  21. package/bundled/examples/blank/template.json +24 -0
  22. package/bundled/examples/blank/templates/404.json +14 -0
  23. package/bundled/examples/blank/templates/account.json +14 -0
  24. package/bundled/examples/blank/templates/article.json +14 -0
  25. package/bundled/examples/blank/templates/blog.json +14 -0
  26. package/bundled/examples/blank/templates/cart.json +14 -0
  27. package/bundled/examples/blank/templates/collection.json +14 -0
  28. package/bundled/examples/blank/templates/index.json +36 -0
  29. package/bundled/examples/blank/templates/page.contact.json +18 -0
  30. package/bundled/examples/blank/templates/page.json +14 -0
  31. package/bundled/examples/blank/templates/product.json +18 -0
  32. package/bundled/examples/blank/templates/search.json +14 -0
  33. package/bundled/examples/blank/tests/theme.test.ts +49 -0
  34. package/bundled/theme-abi/contracts/render-context.v2.d.ts +849 -0
  35. package/bundled/theme-abi/contracts/theme-abi-v2.md +1833 -0
  36. package/bundled/theme-abi/generated/capabilities.json +80 -0
  37. package/bundled/theme-abi/generated/field-types.json +869 -0
  38. package/bundled/theme-abi/generated/limits.json +173 -0
  39. package/bundled/theme-abi/schemas/conformance-report.v2.schema.json +482 -0
  40. package/bundled/theme-abi/schemas/theme-artifact.v1.schema.json +230 -0
  41. package/bundled/theme-abi/schemas/theme-manifest.v2.schema.json +254 -0
  42. package/bundled/theme-conformance/docs/storefront-tier.md +221 -0
  43. package/bundled/theme-conformance/schema/conformance-report.v2.schema.json +482 -0
  44. package/bundled/theme-conformance/schema/storefront-report.v1.schema.json +110 -0
  45. package/bundled/theme-conformance/schema/x-tanqory-ai.v0.schema.json +70 -0
  46. package/bundled/theme-kit/docs/headless-api.md +220 -0
  47. package/bundled/theme-kit/generated/kit-strings.json +180 -0
  48. package/bundled/theme-kit/types/headless/index.d.ts +36 -0
  49. package/bundled/theme-kit/types/headless/theme.d.ts +99 -0
  50. package/bundled/theme-kit/types/sdk/schema.d.ts +197 -0
  51. package/bundled/versions.json +8 -0
  52. package/package.json +53 -3
  53. package/src/bm25.mjs +69 -0
  54. package/src/browser.mjs +123 -0
  55. package/src/cli.mjs +127 -0
  56. package/src/devserver.mjs +82 -0
  57. package/src/docs.mjs +329 -0
  58. package/src/index.mjs +33 -0
  59. package/src/kit.mjs +150 -0
  60. package/src/manifest.mjs +82 -0
  61. package/src/prompts.mjs +97 -0
  62. package/src/scaffold.mjs +471 -0
  63. package/src/schemas.mjs +127 -0
  64. package/src/server.mjs +595 -0
  65. package/src/theme.mjs +91 -0
package/src/theme.mjs ADDED
@@ -0,0 +1,91 @@
1
+ /**
2
+ * The theme this server works on: found from the working directory the agent host started the server in (or
3
+ * TANQORY_THEME_DIR). No argument of any tool names a store or a directory outside it; the store comes from
4
+ * `tanqory.config.json` and the CLI's login.
5
+ */
6
+ import { existsSync, readFileSync, statSync } from 'node:fs'
7
+ import { dirname, isAbsolute, join, relative, resolve, sep } from 'node:path'
8
+
9
+ export const CONFIG_FILE = 'tanqory.config.json'
10
+ export const THEME_PACKAGES = ['@tanqory/theme-abi', '@tanqory/theme-kit', '@tanqory/theme-conformance']
11
+
12
+ const readJson = (p) => {
13
+ try {
14
+ return JSON.parse(readFileSync(p, 'utf8'))
15
+ } catch {
16
+ return null
17
+ }
18
+ }
19
+
20
+ const dependsOnKit = (pkg) =>
21
+ Boolean(pkg && ['dependencies', 'devDependencies'].some((f) => pkg[f] && pkg[f]['@tanqory/theme-kit']))
22
+
23
+ /**
24
+ * Walk up from `start` to the theme root: the first directory with tanqory.config.json, else the first with a
25
+ * package.json that depends on @tanqory/theme-kit. Returns null when there is none (the docs tools still work).
26
+ */
27
+ export function findThemeRoot(start) {
28
+ let dir = resolve(start)
29
+ for (;;) {
30
+ if (existsSync(join(dir, CONFIG_FILE))) return dir
31
+ if (dependsOnKit(readJson(join(dir, 'package.json')))) return dir
32
+ const up = dirname(dir)
33
+ if (up === dir) return null
34
+ dir = up
35
+ }
36
+ }
37
+
38
+ /** The installed package root of `name` as Node would resolve it from `root` (node_modules walk), or null. */
39
+ export function installedPackageDir(root, name) {
40
+ if (!root) return null
41
+ let dir = root
42
+ for (;;) {
43
+ const p = join(dir, 'node_modules', ...name.split('/'))
44
+ if (existsSync(join(p, 'package.json'))) return p
45
+ const up = dirname(dir)
46
+ if (up === dir) return null
47
+ dir = up
48
+ }
49
+ }
50
+
51
+ /** Which source layout the theme uses, so the scaffold knows where a section goes. */
52
+ export function detectLayout(root) {
53
+ if (!root) return 'none'
54
+ const theme = join(root, 'src', 'theme.tsx')
55
+ if (existsSync(theme) && /defineTheme\s*\(/.test(readFileSync(theme, 'utf8'))) return 'kit-headless'
56
+ if (existsSync(join(root, 'theme.config.ts'))) return 'nova-fork'
57
+ return 'unknown'
58
+ }
59
+
60
+ export function loadTheme(cwd) {
61
+ const root = findThemeRoot(process.env.TANQORY_THEME_DIR || cwd)
62
+ if (!root) return { root: null, config: null, pkg: null, layout: 'none', versions: {} }
63
+ const config = readJson(join(root, CONFIG_FILE))
64
+ const pkg = readJson(join(root, 'package.json'))
65
+ const versions = {}
66
+ for (const name of THEME_PACKAGES) {
67
+ const dir = installedPackageDir(root, name)
68
+ versions[name] = dir ? readJson(join(dir, 'package.json'))?.version ?? null : null
69
+ }
70
+ return { root, config, pkg, layout: detectLayout(root), versions }
71
+ }
72
+
73
+ /**
74
+ * Resolve a theme-relative path and refuse anything that escapes the theme root (`..`, absolute paths, symlinked
75
+ * parents are not followed here; writes only ever target paths the scaffold planned itself).
76
+ */
77
+ export function insideTheme(root, rel) {
78
+ if (typeof rel !== 'string' || rel === '' || isAbsolute(rel)) return null
79
+ const abs = resolve(root, rel)
80
+ const r = relative(root, abs)
81
+ if (r === '' || r.startsWith('..') || isAbsolute(r) || r.split(sep).includes('..')) return null
82
+ return abs
83
+ }
84
+
85
+ export const isFile = (p) => {
86
+ try {
87
+ return statSync(p).isFile()
88
+ } catch {
89
+ return false
90
+ }
91
+ }