promptlineapp 1.3.12 → 1.4.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 (3) hide show
  1. package/README.md +3 -5
  2. package/bin/cli.js +42 -43
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -30,20 +30,18 @@ You'll be prompted for:
30
30
 
31
31
  ```bash
32
32
  npx promptlineapp my-app --yes
33
- npx promptlineapp my-app --preset saas -y
33
+ npx promptlineapp my-app --preset full-app -y
34
34
  ```
35
35
 
36
36
  ## Template Presets
37
37
 
38
38
  | Preset | Description | Best For |
39
39
  |--------|-------------|----------|
40
- | `contact` | Landing page + contact form + dashboard | Marketing sites, lead generation |
41
- | `saas` | Full app with auth, dashboard, settings | SaaS products, internal tools |
40
+ | `full-app` | Complete app with landing, dashboard, settings & AI | SaaS products, internal tools (default) |
42
41
  | `api` | Minimal frontend, backend-focused | API services, integrations |
43
- | `blank` | Empty template | Custom builds from scratch |
44
42
 
45
43
  ```bash
46
- npx promptlineapp my-app --preset saas
44
+ npx promptlineapp my-app --preset full-app
47
45
  npx promptlineapp my-api --preset api
48
46
  ```
49
47
 
package/bin/cli.js CHANGED
@@ -1287,28 +1287,35 @@ export default function DevAdminPage() {
1287
1287
 
1288
1288
  const testConnection = async () => {
1289
1289
  if (!endpoint) return
1290
+ if (!apiKey) {
1291
+ setStatus('error')
1292
+ addLog('error', 'API Key required for health check')
1293
+ return
1294
+ }
1290
1295
  setStatus('testing')
1291
1296
  const proxyUrl = toProxyUrl(endpoint)
1292
- const url = proxyUrl.includes('?') ? proxyUrl + '&mode=sync' : proxyUrl + '?mode=sync'
1293
- addLog('info', 'Testing connection...', { endpoint: url, original: endpoint })
1297
+ // Use /isAlive endpoint for health check (no LLM execution, no token consumption)
1298
+ const isAliveUrl = proxyUrl + '/isAlive'
1299
+ addLog('info', 'Testing connection (isAlive)...', { endpoint: isAliveUrl, original: endpoint })
1294
1300
 
1295
1301
  const startTime = Date.now()
1296
1302
  try {
1297
- const res = await fetch(url, {
1298
- method: 'POST',
1303
+ const res = await fetch(isAliveUrl, {
1304
+ method: 'GET',
1299
1305
  headers: {
1300
- 'Content-Type': 'application/json',
1301
- ...(apiKey ? { 'X-API-Key': apiKey } : {})
1302
- },
1303
- body: JSON.stringify({ input: { text: 'test' }, variables: {} })
1306
+ 'X-API-Key': apiKey
1307
+ }
1304
1308
  })
1309
+ const data = await res.json().catch(() => ({}))
1305
1310
  const duration = Date.now() - startTime
1306
1311
 
1307
- if (res.ok) {
1312
+ if (res.ok && data.alive === true) {
1308
1313
  setStatus('connected')
1309
- addLog('success', 'Connected (' + duration + 'ms)', { status: res.status })
1314
+ addLog('success', 'Endpoint is alive (' + duration + 'ms)', { alive: true })
1315
+ } else if (res.ok && data.alive === false) {
1316
+ setStatus('error')
1317
+ addLog('error', 'Endpoint exists but is inactive (' + duration + 'ms)', { alive: false })
1310
1318
  } else {
1311
- const data = await res.json().catch(() => ({}))
1312
1319
  setStatus('error')
1313
1320
  addLog('error', res.status + ' ' + res.statusText + ' (' + duration + 'ms)', data)
1314
1321
  }
@@ -1317,7 +1324,7 @@ export default function DevAdminPage() {
1317
1324
  setStatus('error')
1318
1325
  addLog('error', 'Network error (' + duration + 'ms)', {
1319
1326
  message: err.message,
1320
- hint: err.message.includes('Failed to fetch') ? 'CORS issue - server needs Access-Control-Allow-Origin header' : null
1327
+ hint: err.message.includes('Failed to fetch') ? 'CORS issue or endpoint not found' : null
1321
1328
  })
1322
1329
  }
1323
1330
  }
@@ -1410,7 +1417,7 @@ export default function DevAdminPage() {
1410
1417
  className="w-full bg-gray-700 p-3 rounded text-white font-mono text-sm"
1411
1418
  placeholder="Your API key..."
1412
1419
  />
1413
- <p className="text-xs text-gray-500 mt-1">Get your API key from /api-keys</p>
1420
+ <p className="text-xs text-gray-500 mt-1">Required for health check. Get from /api-keys</p>
1414
1421
  </div>
1415
1422
 
1416
1423
  <div className="flex gap-3">
@@ -1423,10 +1430,11 @@ export default function DevAdminPage() {
1423
1430
  </button>
1424
1431
  <button
1425
1432
  onClick={testConnection}
1426
- disabled={!endpoint || status === 'testing'}
1433
+ disabled={!endpoint || !apiKey || status === 'testing'}
1427
1434
  className="px-6 py-2 bg-gray-600 rounded font-medium hover:bg-gray-500 disabled:opacity-50 flex items-center gap-2"
1435
+ title="Uses /isAlive endpoint (no LLM cost)"
1428
1436
  >
1429
- {status === 'testing' ? 'Testing...' : 'Test Connection'}
1437
+ {status === 'testing' ? 'Checking...' : 'Check Health'}
1430
1438
  {status === 'connected' && <span className="text-green-400">●</span>}
1431
1439
  {status === 'error' && <span className="text-red-400">●</span>}
1432
1440
  </button>
@@ -1621,7 +1629,7 @@ async function createPackage(name, options = {}) {
1621
1629
  description: 'My PromptLine application',
1622
1630
  primaryColor: '#6366f1',
1623
1631
  contactEmail: 'contact@example.com',
1624
- preset: options.preset || 'contact',
1632
+ preset: options.preset || 'full-app',
1625
1633
  };
1626
1634
 
1627
1635
  // Interactive mode
@@ -1683,10 +1691,8 @@ async function createPackage(name, options = {}) {
1683
1691
 
1684
1692
  if (!options.preset) {
1685
1693
  const presets = [
1686
- { name: 'Contact Form', description: 'Landing + form + dashboard', value: 'contact' },
1687
- { name: 'SaaS', description: 'Full app with auth & billing', value: 'saas' },
1688
- { name: 'API', description: 'Backend-focused, minimal UI', value: 'api' },
1689
- { name: 'Blank', description: 'Empty template', value: 'blank' },
1694
+ { name: 'Full App', description: 'Complete app with pages, dashboard & AI', value: 'full-app' },
1695
+ { name: 'API', description: 'Backend-focused, minimal frontend', value: 'api' },
1690
1696
  ];
1691
1697
  config.preset = await prompt.select('Select a template:', presets);
1692
1698
  }
@@ -1715,25 +1721,20 @@ async function createPackage(name, options = {}) {
1715
1721
  success('Created assets/');
1716
1722
 
1717
1723
  // Create files based on preset
1718
- if (config.preset === 'blank') {
1719
- fs.writeFileSync(path.join(targetDir, 'public', 'index.tsx'), templates.blankIndex(config));
1720
- success('Created public/index.tsx');
1721
- } else {
1722
- // Contact, SaaS, API all start with similar base
1723
- fs.writeFileSync(path.join(targetDir, 'public', 'index.tsx'), templates.publicIndex(config));
1724
- success('Created public/index.tsx');
1725
-
1726
- if (config.preset !== 'api') {
1727
- fs.writeFileSync(path.join(targetDir, 'private', 'dashboard.tsx'), templates.privateDashboard(config));
1728
- fs.writeFileSync(path.join(targetDir, 'private', 'settings.tsx'), templates.privateSettings(config));
1729
- success('Created private/dashboard.tsx');
1730
- success('Created private/settings.tsx');
1731
- }
1732
-
1733
- fs.writeFileSync(path.join(targetDir, 'backend', 'api.py'), templates.backendApi(config));
1734
- success('Created backend/api.py');
1724
+ fs.writeFileSync(path.join(targetDir, 'public', 'index.tsx'), templates.publicIndex(config));
1725
+ success('Created public/index.tsx');
1726
+
1727
+ if (config.preset !== 'api') {
1728
+ // Full-app preset gets dashboard and settings pages
1729
+ fs.writeFileSync(path.join(targetDir, 'private', 'dashboard.tsx'), templates.privateDashboard(config));
1730
+ fs.writeFileSync(path.join(targetDir, 'private', 'settings.tsx'), templates.privateSettings(config));
1731
+ success('Created private/dashboard.tsx');
1732
+ success('Created private/settings.tsx');
1735
1733
  }
1736
1734
 
1735
+ fs.writeFileSync(path.join(targetDir, 'backend', 'api.py'), templates.backendApi(config));
1736
+ success('Created backend/api.py');
1737
+
1737
1738
  // Common files
1738
1739
  fs.writeFileSync(path.join(targetDir, 'promptline.yaml'), templates.config(config));
1739
1740
  success('Created promptline.yaml');
@@ -1750,7 +1751,7 @@ async function createPackage(name, options = {}) {
1750
1751
 
1751
1752
  // Collect page names for router
1752
1753
  const pages = { public: ['index'], private: [] };
1753
- if (config.preset !== 'blank' && config.preset !== 'api') {
1754
+ if (config.preset !== 'api') {
1754
1755
  pages.private = ['dashboard', 'settings'];
1755
1756
  }
1756
1757
 
@@ -1855,7 +1856,7 @@ ${c.bold}Usage:${c.reset}
1855
1856
  npx create-promptline-app <app-name> [options]
1856
1857
 
1857
1858
  ${c.bold}Options:${c.reset}
1858
- -p, --preset <preset> Template preset (contact, saas, api, blank)
1859
+ -p, --preset <preset> Template preset (full-app, api)
1859
1860
  -y, --yes Skip prompts, use defaults
1860
1861
  -h, --help Show this help
1861
1862
  -v, --version Show version
@@ -1866,10 +1867,8 @@ ${c.bold}Examples:${c.reset}
1866
1867
  npx create-promptline-app my-app -y
1867
1868
 
1868
1869
  ${c.bold}Presets:${c.reset}
1869
- contact Landing page + contact form + dashboard (default)
1870
- saas Full SaaS with auth, dashboard, billing
1871
- api Backend-focused, minimal frontend
1872
- blank Empty template
1870
+ full-app Complete app with pages, dashboard & AI (default)
1871
+ api Backend-focused, minimal frontend
1873
1872
 
1874
1873
  ${c.bold}Documentation:${c.reset}
1875
1874
  https://docs.promptlineops.com/packages
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "promptlineapp",
3
- "version": "1.3.12",
3
+ "version": "1.4.1",
4
4
  "description": "Create PromptLine applications with ease",
5
5
  "author": "PromptLine <support@promptlineops.com>",
6
6
  "license": "MIT",