@peume/cli 0.1.0 → 0.2.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.
- package/README.md +9 -1
- package/package.json +1 -1
- package/peume.mjs +31 -2
package/README.md
CHANGED
|
@@ -25,4 +25,12 @@ npx @peume/cli env set KEY=value # set variables, then redeploy
|
|
|
25
25
|
- `node_modules`, `.git` and build caches are not uploaded.
|
|
26
26
|
- A new app stops after 24 h unless you claim it (free) with the link shown after the deploy.
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
## Built in
|
|
29
|
+
|
|
30
|
+
Every app gets `PEUME_KEY` and `PEUME_API`:
|
|
31
|
+
|
|
32
|
+
- **Peume Data**: hundreds of data tools (scraping, search, maps, social…).
|
|
33
|
+
- **Peume Routing**: every AI model through the OpenAI SDK, no other account.
|
|
34
|
+
- **Payments**: get paid in your app, money goes to your own Stripe account.
|
|
35
|
+
|
|
36
|
+
Docs: https://cloud.peume.com/docs
|
package/package.json
CHANGED
package/peume.mjs
CHANGED
|
@@ -11,7 +11,7 @@ import { createInterface } from 'node:readline';
|
|
|
11
11
|
const PEUME = (process.env.PEUME_URL || 'https://cloud.peume.com').replace(/\/$/, '');
|
|
12
12
|
const JETONS = join(homedir(), '.peume', 'jetons.json');
|
|
13
13
|
const EXCLUS = ['node_modules', '.git', '.next', '.nuxt', '.svelte-kit', '.vercel', '.turbo', '.cache', '.DS_Store', '.peume', '__pycache__', '.venv', 'venv', '.idea', '.vscode', '*.log'];
|
|
14
|
-
const VERSION = '0.
|
|
14
|
+
const VERSION = '0.2.0';
|
|
15
15
|
|
|
16
16
|
const lireJSON = async (f, d) => { try { return JSON.parse(await readFile(f, 'utf8')); } catch { return d; } };
|
|
17
17
|
async function lien(dossier) {
|
|
@@ -91,6 +91,23 @@ async function logs(dossier) {
|
|
|
91
91
|
if (!app) throw new Error('This folder is not deployed yet.');
|
|
92
92
|
return (await appel(`/api/apps/${app}/logs`, { entetes: auth(jeton) })).logs;
|
|
93
93
|
}
|
|
94
|
+
// Peume Data (outils de données via Peume, payés en crédits Peume) avec l'identité de l'app du dossier
|
|
95
|
+
async function data(dossier, chemin, corps) {
|
|
96
|
+
const { app, jeton } = await lien(resolve(dossier));
|
|
97
|
+
if (!app) throw new Error('Deploy this folder on Peume first (deploy tool), then claim the app to use Peume Data.');
|
|
98
|
+
return appel(`/api/v1/data${chemin}`, { methode: corps ? 'POST' : 'GET', corps: corps && JSON.stringify(corps), entetes: { 'content-type': 'application/json', 'x-peume-app': app, ...auth(jeton) }, delai: 60000 });
|
|
99
|
+
}
|
|
100
|
+
async function lancerData(dossier, args) {
|
|
101
|
+
let r = await data(dossier, '/run', { provider: args.provider, endpoint: args.endpoint, input: args.input || {} });
|
|
102
|
+
const fin = Date.now() + 120e3;
|
|
103
|
+
while (!['COMPLETED', 'FAILED', 'BLOCKED', 'STOPPED', 'TIMED_OUT'].includes(r.status) && Date.now() < fin) {
|
|
104
|
+
await new Promise(t => setTimeout(t, 5000));
|
|
105
|
+
r = await data(dossier, `/runs/${r.runId}`);
|
|
106
|
+
}
|
|
107
|
+
const sortie = JSON.stringify(r.output ?? r.error ?? null, null, 2);
|
|
108
|
+
return `Run ${r.runId}: ${r.status}${r.cost ? ` · $${r.cost.value.toFixed(4)}` : ''}\n${sortie.length > 20000 ? `${sortie.slice(0, 20000)}\n… (truncated)` : sortie}`;
|
|
109
|
+
}
|
|
110
|
+
|
|
94
111
|
async function variables(dossier, paires) {
|
|
95
112
|
const { app, jeton } = await lien(resolve(dossier));
|
|
96
113
|
if (!app) throw new Error('This folder is not deployed yet.');
|
|
@@ -101,8 +118,16 @@ async function variables(dossier, paires) {
|
|
|
101
118
|
|
|
102
119
|
// ——— serveur MCP (stdio) pour Claude Code : claude mcp add peume -- npx -y @peume/cli mcp
|
|
103
120
|
const OUTILS = [
|
|
104
|
-
{ name: 'deploy', description: 'Deploy a project folder on Peume (free, no account needed) and wait for the build. Returns the live URL (name.peume.com), or the build logs if it failed so you can fix the code and deploy again. The app must listen on the PORT environment variable. Variables in .env are set on the app, never uploaded as files.',
|
|
121
|
+
{ name: 'deploy', description: 'Deploy a project folder on Peume (free, no account needed) and wait for the build. Returns the live URL (name.peume.com), or the build logs if it failed so you can fix the code and deploy again. The app must listen on the PORT environment variable. Variables in .env are set on the app, never uploaded as files. The app also gets PEUME_KEY and PEUME_API for Peume Data and payments (see the services tool).',
|
|
105
122
|
inputSchema: { type: 'object', properties: { path: { type: 'string', description: 'Absolute path of the project folder.' }, name: { type: 'string', description: 'Wanted app name for the first deploy (becomes name.peume.com). Defaults to the folder name.' } }, required: ['path'] } },
|
|
123
|
+
{ name: 'services', description: 'How the deployed app can use Peume services from its server code: Peume Data (hundreds of data tools: scraping, search, maps, social, companies), Peume Routing (every AI model through the OpenAI SDK, no other API key) and payments (Stripe checkout, money goes to the owner). Every Peume app gets PEUME_KEY and PEUME_API environment variables. Read this before adding data or payments to an app deployed on Peume.',
|
|
124
|
+
inputSchema: { type: 'object', properties: {} } },
|
|
125
|
+
{ name: 'data_search', description: 'Search Peume Data tools for a need (e.g. "google maps reviews", "linkedin profiles"). Free. Returns provider, endpoint, description and price per call.',
|
|
126
|
+
inputSchema: { type: 'object', properties: { path: { type: 'string', description: 'Absolute path of the deployed project folder.' }, query: { type: 'string' } }, required: ['path', 'query'] } },
|
|
127
|
+
{ name: 'data_inspect', description: 'Get the exact input schema (body, queryParams, pathParams) and price of a Peume Data tool. Free. Always inspect before running.',
|
|
128
|
+
inputSchema: { type: 'object', properties: { path: { type: 'string', description: 'Absolute path of the deployed project folder.' }, provider: { type: 'string' }, endpoint: { type: 'string' } }, required: ['path', 'provider', 'endpoint'] } },
|
|
129
|
+
{ name: 'data_run', description: 'Run a Peume Data tool once (to test it while building the app) and wait up to 2 minutes for the result. Paid from the app owner\'s Peume credits: keep limits small (maxItems 5-10, one query).',
|
|
130
|
+
inputSchema: { type: 'object', properties: { path: { type: 'string', description: 'Absolute path of the deployed project folder.' }, provider: { type: 'string' }, endpoint: { type: 'string' }, input: { type: 'object', description: '{ body?, queryParams?, pathParams? } as given by data_inspect.' } }, required: ['path', 'provider', 'endpoint'] } },
|
|
106
131
|
{ name: 'status', description: 'Status of the Peume app deployed from this folder: URL, state and the latest build logs.',
|
|
107
132
|
inputSchema: { type: 'object', properties: { path: { type: 'string', description: 'Absolute path of the project folder.' } }, required: ['path'] } },
|
|
108
133
|
{ name: 'logs', description: 'Runtime logs of the running Peume app deployed from this folder.',
|
|
@@ -111,7 +136,11 @@ const OUTILS = [
|
|
|
111
136
|
inputSchema: { type: 'object', properties: { path: { type: 'string', description: 'Absolute path of the project folder.' }, vars: { type: 'object', additionalProperties: { type: 'string' }, description: 'Variables to set, e.g. {"API_KEY": "…"}.' } }, required: ['path', 'vars'] } },
|
|
112
137
|
];
|
|
113
138
|
async function outil(nom, args = {}) {
|
|
139
|
+
if (nom === 'services') { const r = await fetch(`${PEUME}/docs.md`, { signal: AbortSignal.timeout(15000) }); return r.ok ? r.text() : 'Docs: https://cloud.peume.com/docs'; }
|
|
114
140
|
if (!args.path) throw new Error('path is required.');
|
|
141
|
+
if (nom === 'data_search') return JSON.stringify(await data(args.path, '/search', { query: args.query, limit: 10 }), null, 2);
|
|
142
|
+
if (nom === 'data_inspect') return JSON.stringify(await data(args.path, '/inspect', { provider: args.provider, endpoint: args.endpoint }), null, 2);
|
|
143
|
+
if (nom === 'data_run') return lancerData(args.path, args);
|
|
115
144
|
if (nom === 'deploy') return resume(await deployer(args.path, { nom: args.name }));
|
|
116
145
|
if (nom === 'status') { const { e } = await etat(args.path); return `${e.url} — ${e.statut}${e.deploiement ? ` (last build: ${e.deploiement.statut}, ${e.deploiement.commit})` : ''}\n${resume(e)}`; }
|
|
117
146
|
if (nom === 'logs') return (await logs(args.path)).join('\n') || 'No logs yet.';
|