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.
- package/README.md +3 -5
- package/bin/cli.js +42 -43
- 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
|
|
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
|
-
| `
|
|
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
|
|
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
|
-
|
|
1293
|
-
|
|
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(
|
|
1298
|
-
method: '
|
|
1303
|
+
const res = await fetch(isAliveUrl, {
|
|
1304
|
+
method: 'GET',
|
|
1299
1305
|
headers: {
|
|
1300
|
-
'
|
|
1301
|
-
|
|
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', '
|
|
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
|
|
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">
|
|
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' ? '
|
|
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 || '
|
|
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: '
|
|
1687
|
-
{ name: '
|
|
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
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
//
|
|
1723
|
-
fs.writeFileSync(path.join(targetDir, '
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
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 !== '
|
|
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 (
|
|
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
|
-
|
|
1870
|
-
|
|
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
|