@neetru/cli 2.7.5 → 2.9.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/CHANGELOG.md +316 -220
- package/README.md +137 -137
- package/dist/cli-kit/format.d.ts +49 -0
- package/dist/cli-kit/format.js +88 -0
- package/dist/cli-kit/format.js.map +1 -0
- package/dist/cli-kit/glyphs.d.ts +22 -0
- package/dist/cli-kit/glyphs.js +22 -0
- package/dist/cli-kit/glyphs.js.map +1 -0
- package/dist/cli-kit/index.d.ts +13 -0
- package/dist/cli-kit/index.js +12 -0
- package/dist/cli-kit/index.js.map +1 -0
- package/dist/cli-kit/palette.d.ts +10 -0
- package/dist/cli-kit/palette.js +36 -0
- package/dist/cli-kit/palette.js.map +1 -0
- package/dist/commands/ai.js +8 -8
- package/dist/commands/autocomplete.js +34 -34
- package/dist/commands/bug.d.ts +87 -0
- package/dist/commands/bug.js +419 -0
- package/dist/commands/bug.js.map +1 -0
- package/dist/commands/customers.d.ts +17 -0
- package/dist/commands/customers.js +160 -0
- package/dist/commands/customers.js.map +1 -0
- package/dist/commands/db.d.ts +91 -7
- package/dist/commands/db.js +898 -123
- package/dist/commands/db.js.map +1 -1
- package/dist/commands/deploy.d.ts +5 -0
- package/dist/commands/deploy.js +68 -0
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/dev.d.ts +68 -0
- package/dist/commands/dev.js +345 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/docs.d.ts +4 -0
- package/dist/commands/docs.js +99 -7
- package/dist/commands/docs.js.map +1 -1
- package/dist/commands/doctor.js +4 -1
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/init.js +121 -121
- package/dist/commands/marketplace.d.ts +36 -0
- package/dist/commands/marketplace.js +584 -0
- package/dist/commands/marketplace.js.map +1 -0
- package/dist/commands/new.d.ts +6 -0
- package/dist/commands/new.js +220 -40
- package/dist/commands/new.js.map +1 -1
- package/dist/commands/open.d.ts +8 -0
- package/dist/commands/open.js +61 -13
- package/dist/commands/open.js.map +1 -1
- package/dist/commands/products-db.d.ts +1 -1
- package/dist/commands/products-db.js +17 -4
- package/dist/commands/products-db.js.map +1 -1
- package/dist/commands/products.d.ts +23 -0
- package/dist/commands/products.js +39 -1
- package/dist/commands/products.js.map +1 -1
- package/dist/commands/tenants.js +15 -0
- package/dist/commands/tenants.js.map +1 -1
- package/dist/commands/ui.d.ts +1 -1
- package/dist/commands/ui.js +172 -2
- package/dist/commands/ui.js.map +1 -1
- package/dist/commands/workspaces.d.ts +10 -1
- package/dist/commands/workspaces.js +136 -22
- package/dist/commands/workspaces.js.map +1 -1
- package/dist/index.js +532 -44
- package/dist/index.js.map +1 -1
- package/dist/lib/ai/context.js +90 -90
- package/dist/lib/config-schema.d.ts +8 -8
- package/dist/lib/db-local/db-json.d.ts +63 -0
- package/dist/lib/db-local/db-json.js +189 -0
- package/dist/lib/db-local/db-json.js.map +1 -0
- package/dist/lib/db-local/env.d.ts +26 -0
- package/dist/lib/db-local/env.js +64 -0
- package/dist/lib/db-local/env.js.map +1 -0
- package/dist/lib/db-local/fingerprint.d.ts +8 -0
- package/dist/lib/db-local/fingerprint.js +28 -0
- package/dist/lib/db-local/fingerprint.js.map +1 -0
- package/dist/lib/db-local/index.d.ts +15 -0
- package/dist/lib/db-local/index.js +14 -0
- package/dist/lib/db-local/index.js.map +1 -0
- package/dist/lib/db-pipeline/build-deps.d.ts +14 -0
- package/dist/lib/db-pipeline/build-deps.js +158 -0
- package/dist/lib/db-pipeline/build-deps.js.map +1 -0
- package/dist/lib/db-pipeline/errors.d.ts +29 -0
- package/dist/lib/db-pipeline/errors.js +29 -0
- package/dist/lib/db-pipeline/errors.js.map +1 -0
- package/dist/lib/db-pipeline/index.d.ts +26 -0
- package/dist/lib/db-pipeline/index.js +25 -0
- package/dist/lib/db-pipeline/index.js.map +1 -0
- package/dist/lib/db-pipeline/pipeline.d.ts +13 -0
- package/dist/lib/db-pipeline/pipeline.js +119 -0
- package/dist/lib/db-pipeline/pipeline.js.map +1 -0
- package/dist/lib/db-pipeline/rehearse.d.ts +99 -0
- package/dist/lib/db-pipeline/rehearse.js +219 -0
- package/dist/lib/db-pipeline/rehearse.js.map +1 -0
- package/dist/lib/db-pipeline/types.d.ts +112 -0
- package/dist/lib/db-pipeline/types.js +20 -0
- package/dist/lib/db-pipeline/types.js.map +1 -0
- package/dist/lib/pickers.d.ts +12 -0
- package/dist/lib/pickers.js +34 -0
- package/dist/lib/pickers.js.map +1 -1
- package/package.json +66 -62
- package/templates/auth/callback.ts +22 -22
- package/templates/auth/sign-in.tsx +41 -41
- package/templates/billing/checkout.ts +22 -22
- package/templates/billing/page.tsx +43 -43
- package/templates/support/ticket-form.tsx +68 -68
- package/templates/usage/track.ts +30 -30
- package/templates/users/profile.tsx +43 -43
package/dist/commands/init.js
CHANGED
|
@@ -298,96 +298,96 @@ async function scaffoldNextjs(dir, name, write) {
|
|
|
298
298
|
},
|
|
299
299
|
}, null, 2));
|
|
300
300
|
// next.config.mjs
|
|
301
|
-
await write(path.join(dir, 'next.config.mjs'), `/** @type {import('next').NextConfig} */
|
|
302
|
-
const nextConfig = {};
|
|
303
|
-
export default nextConfig;
|
|
301
|
+
await write(path.join(dir, 'next.config.mjs'), `/** @type {import('next').NextConfig} */
|
|
302
|
+
const nextConfig = {};
|
|
303
|
+
export default nextConfig;
|
|
304
304
|
`);
|
|
305
305
|
// Layout raiz
|
|
306
|
-
await write(path.join(dir, 'src', 'app', 'layout.tsx'), `import type { Metadata } from 'next';
|
|
307
|
-
|
|
308
|
-
export const metadata: Metadata = {
|
|
309
|
-
title: '${name}',
|
|
310
|
-
};
|
|
311
|
-
|
|
312
|
-
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
313
|
-
return (
|
|
314
|
-
<html lang="pt-BR">
|
|
315
|
-
<body>{children}</body>
|
|
316
|
-
</html>
|
|
317
|
-
);
|
|
318
|
-
}
|
|
306
|
+
await write(path.join(dir, 'src', 'app', 'layout.tsx'), `import type { Metadata } from 'next';
|
|
307
|
+
|
|
308
|
+
export const metadata: Metadata = {
|
|
309
|
+
title: '${name}',
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
313
|
+
return (
|
|
314
|
+
<html lang="pt-BR">
|
|
315
|
+
<body>{children}</body>
|
|
316
|
+
</html>
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
319
|
`);
|
|
320
320
|
// Página inicial com auth gate via SDK 1.1
|
|
321
|
-
await write(path.join(dir, 'src', 'app', 'page.tsx'), `// Produto Neetru — gerado por neetru init
|
|
322
|
-
// Auth via @neetru/sdk client (createNeetruClient + auth namespace)
|
|
323
|
-
|
|
324
|
-
'use client';
|
|
325
|
-
|
|
326
|
-
import { createNeetruClient } from '@neetru/sdk';
|
|
327
|
-
import { useEffect, useState } from 'react';
|
|
328
|
-
import type { NeetruUser } from '@neetru/sdk';
|
|
329
|
-
|
|
330
|
-
const neetru = createNeetruClient({
|
|
331
|
-
apiKey: process.env.NEXT_PUBLIC_NEETRU_API_KEY,
|
|
332
|
-
env: (process.env.NEXT_PUBLIC_NEETRU_ENV as 'dev' | 'prod') ?? 'dev',
|
|
333
|
-
});
|
|
334
|
-
|
|
335
|
-
export default function HomePage() {
|
|
336
|
-
const [user, setUser] = useState<NeetruUser | null>(null);
|
|
337
|
-
const [loading, setLoading] = useState(true);
|
|
338
|
-
|
|
339
|
-
useEffect(() => {
|
|
340
|
-
let unsub: (() => void) | undefined;
|
|
341
|
-
neetru.auth.getUser().then((u) => {
|
|
342
|
-
setUser(u);
|
|
343
|
-
setLoading(false);
|
|
344
|
-
});
|
|
345
|
-
unsub = neetru.auth.onAuthStateChanged((u) => setUser(u));
|
|
346
|
-
return () => unsub?.();
|
|
347
|
-
}, []);
|
|
348
|
-
|
|
349
|
-
if (loading) return <main><p>Carregando...</p></main>;
|
|
350
|
-
if (!user) {
|
|
351
|
-
return (
|
|
352
|
-
<main>
|
|
353
|
-
<h1>${name}</h1>
|
|
354
|
-
<button onClick={() => neetru.auth.signIn()}>Entrar com Neetru</button>
|
|
355
|
-
</main>
|
|
356
|
-
);
|
|
357
|
-
}
|
|
358
|
-
return (
|
|
359
|
-
<main>
|
|
360
|
-
<h1>Bem-vindo, {user.email}</h1>
|
|
361
|
-
<p>UID: {user.uid}</p>
|
|
362
|
-
<button onClick={() => neetru.auth.signOut()}>Sair</button>
|
|
363
|
-
</main>
|
|
364
|
-
);
|
|
365
|
-
}
|
|
321
|
+
await write(path.join(dir, 'src', 'app', 'page.tsx'), `// Produto Neetru — gerado por neetru init
|
|
322
|
+
// Auth via @neetru/sdk client (createNeetruClient + auth namespace)
|
|
323
|
+
|
|
324
|
+
'use client';
|
|
325
|
+
|
|
326
|
+
import { createNeetruClient } from '@neetru/sdk';
|
|
327
|
+
import { useEffect, useState } from 'react';
|
|
328
|
+
import type { NeetruUser } from '@neetru/sdk';
|
|
329
|
+
|
|
330
|
+
const neetru = createNeetruClient({
|
|
331
|
+
apiKey: process.env.NEXT_PUBLIC_NEETRU_API_KEY,
|
|
332
|
+
env: (process.env.NEXT_PUBLIC_NEETRU_ENV as 'dev' | 'prod') ?? 'dev',
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
export default function HomePage() {
|
|
336
|
+
const [user, setUser] = useState<NeetruUser | null>(null);
|
|
337
|
+
const [loading, setLoading] = useState(true);
|
|
338
|
+
|
|
339
|
+
useEffect(() => {
|
|
340
|
+
let unsub: (() => void) | undefined;
|
|
341
|
+
neetru.auth.getUser().then((u) => {
|
|
342
|
+
setUser(u);
|
|
343
|
+
setLoading(false);
|
|
344
|
+
});
|
|
345
|
+
unsub = neetru.auth.onAuthStateChanged((u) => setUser(u));
|
|
346
|
+
return () => unsub?.();
|
|
347
|
+
}, []);
|
|
348
|
+
|
|
349
|
+
if (loading) return <main><p>Carregando...</p></main>;
|
|
350
|
+
if (!user) {
|
|
351
|
+
return (
|
|
352
|
+
<main>
|
|
353
|
+
<h1>${name}</h1>
|
|
354
|
+
<button onClick={() => neetru.auth.signIn()}>Entrar com Neetru</button>
|
|
355
|
+
</main>
|
|
356
|
+
);
|
|
357
|
+
}
|
|
358
|
+
return (
|
|
359
|
+
<main>
|
|
360
|
+
<h1>Bem-vindo, {user.email}</h1>
|
|
361
|
+
<p>UID: {user.uid}</p>
|
|
362
|
+
<button onClick={() => neetru.auth.signOut()}>Sair</button>
|
|
363
|
+
</main>
|
|
364
|
+
);
|
|
365
|
+
}
|
|
366
366
|
`);
|
|
367
367
|
// Middleware Next.js — gate de cookie de sessão em rotas privadas
|
|
368
|
-
await write(path.join(dir, 'src', 'middleware.ts'), `import { NextRequest, NextResponse } from 'next/server';
|
|
369
|
-
|
|
370
|
-
const PUBLIC_PATHS = ['/login', '/api/auth', '/_next', '/favicon.ico'];
|
|
371
|
-
|
|
372
|
-
export function middleware(request: NextRequest) {
|
|
373
|
-
const { pathname } = request.nextUrl;
|
|
374
|
-
if (PUBLIC_PATHS.some((p) => pathname.startsWith(p))) {
|
|
375
|
-
return NextResponse.next();
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
const hasSession = request.cookies.has('__session');
|
|
379
|
-
if (!hasSession) {
|
|
380
|
-
const url = request.nextUrl.clone();
|
|
381
|
-
url.pathname = '/login';
|
|
382
|
-
return NextResponse.redirect(url);
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
return NextResponse.next();
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
export const config = {
|
|
389
|
-
matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
|
|
390
|
-
};
|
|
368
|
+
await write(path.join(dir, 'src', 'middleware.ts'), `import { NextRequest, NextResponse } from 'next/server';
|
|
369
|
+
|
|
370
|
+
const PUBLIC_PATHS = ['/login', '/api/auth', '/_next', '/favicon.ico'];
|
|
371
|
+
|
|
372
|
+
export function middleware(request: NextRequest) {
|
|
373
|
+
const { pathname } = request.nextUrl;
|
|
374
|
+
if (PUBLIC_PATHS.some((p) => pathname.startsWith(p))) {
|
|
375
|
+
return NextResponse.next();
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
const hasSession = request.cookies.has('__session');
|
|
379
|
+
if (!hasSession) {
|
|
380
|
+
const url = request.nextUrl.clone();
|
|
381
|
+
url.pathname = '/login';
|
|
382
|
+
return NextResponse.redirect(url);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
return NextResponse.next();
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
export const config = {
|
|
389
|
+
matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
|
|
390
|
+
};
|
|
391
391
|
`);
|
|
392
392
|
// tsconfig.json
|
|
393
393
|
await write(path.join(dir, 'tsconfig.json'), JSON.stringify({
|
|
@@ -433,43 +433,43 @@ async function scaffoldNodeApi(dir, name, write) {
|
|
|
433
433
|
'@types/node': '^22.0.0',
|
|
434
434
|
},
|
|
435
435
|
}, null, 2));
|
|
436
|
-
await write(path.join(dir, 'src', 'index.ts'), `import Fastify from 'fastify';
|
|
437
|
-
import { createNeetruClient } from '@neetru/sdk';
|
|
438
|
-
|
|
439
|
-
// Padrão @neetru/sdk@1.1 — namespaces server-side: entitlements/usage/telemetry.
|
|
440
|
-
const neetru = createNeetruClient({
|
|
441
|
-
apiKey: process.env.NEETRU_API_KEY,
|
|
442
|
-
env: (process.env.NEETRU_ENV as 'dev' | 'prod') ?? 'dev',
|
|
443
|
-
});
|
|
444
|
-
|
|
445
|
-
const PRODUCT_SLUG = process.env.NEETRU_PRODUCT_SLUG ?? '${name}';
|
|
446
|
-
|
|
447
|
-
const app = Fastify({ logger: true });
|
|
448
|
-
|
|
449
|
-
function requireEntitlement(feature: string) {
|
|
450
|
-
return async (
|
|
451
|
-
_request: import('fastify').FastifyRequest,
|
|
452
|
-
reply: import('fastify').FastifyReply,
|
|
453
|
-
) => {
|
|
454
|
-
const allowed = await neetru.entitlements.check(PRODUCT_SLUG, feature);
|
|
455
|
-
if (!allowed) {
|
|
456
|
-
return reply.code(403).send({ error: 'entitlement_denied', feature });
|
|
457
|
-
}
|
|
458
|
-
};
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
app.get('/health', async () => ({ status: 'ok' }));
|
|
462
|
-
|
|
463
|
-
app.get(
|
|
464
|
-
'/api/data',
|
|
465
|
-
{ preHandler: requireEntitlement('api-access') },
|
|
466
|
-
async () => {
|
|
467
|
-
await neetru.usage.report('api_call', 1, { productId: PRODUCT_SLUG });
|
|
468
|
-
return { data: [] };
|
|
469
|
-
},
|
|
470
|
-
);
|
|
471
|
-
|
|
472
|
-
await app.listen({ port: 3000, host: '0.0.0.0' });
|
|
436
|
+
await write(path.join(dir, 'src', 'index.ts'), `import Fastify from 'fastify';
|
|
437
|
+
import { createNeetruClient } from '@neetru/sdk';
|
|
438
|
+
|
|
439
|
+
// Padrão @neetru/sdk@1.1 — namespaces server-side: entitlements/usage/telemetry.
|
|
440
|
+
const neetru = createNeetruClient({
|
|
441
|
+
apiKey: process.env.NEETRU_API_KEY,
|
|
442
|
+
env: (process.env.NEETRU_ENV as 'dev' | 'prod') ?? 'dev',
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
const PRODUCT_SLUG = process.env.NEETRU_PRODUCT_SLUG ?? '${name}';
|
|
446
|
+
|
|
447
|
+
const app = Fastify({ logger: true });
|
|
448
|
+
|
|
449
|
+
function requireEntitlement(feature: string) {
|
|
450
|
+
return async (
|
|
451
|
+
_request: import('fastify').FastifyRequest,
|
|
452
|
+
reply: import('fastify').FastifyReply,
|
|
453
|
+
) => {
|
|
454
|
+
const allowed = await neetru.entitlements.check(PRODUCT_SLUG, feature);
|
|
455
|
+
if (!allowed) {
|
|
456
|
+
return reply.code(403).send({ error: 'entitlement_denied', feature });
|
|
457
|
+
}
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
app.get('/health', async () => ({ status: 'ok' }));
|
|
462
|
+
|
|
463
|
+
app.get(
|
|
464
|
+
'/api/data',
|
|
465
|
+
{ preHandler: requireEntitlement('api-access') },
|
|
466
|
+
async () => {
|
|
467
|
+
await neetru.usage.report('api_call', 1, { productId: PRODUCT_SLUG });
|
|
468
|
+
return { data: [] };
|
|
469
|
+
},
|
|
470
|
+
);
|
|
471
|
+
|
|
472
|
+
await app.listen({ port: 3000, host: '0.0.0.0' });
|
|
473
473
|
`);
|
|
474
474
|
}
|
|
475
475
|
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export declare function getCacheDir(): string;
|
|
2
|
+
/**
|
|
3
|
+
* Resolve o diretorio fonte das skills no cache local.
|
|
4
|
+
*
|
|
5
|
+
* Suporta 2 estruturas no repo neetru-libs/claude-skills/:
|
|
6
|
+
*
|
|
7
|
+
* 1. Marketplace estruturado (atual): plugins/PLUGIN/skills/SKILL/SKILL.md
|
|
8
|
+
* - descobre todos os plugins/PLUGIN/skills/ e retorna o primeiro.
|
|
9
|
+
* 2. Plugin direto (legado): skills/SKILL/SKILL.md
|
|
10
|
+
* - retorna single path.
|
|
11
|
+
*
|
|
12
|
+
* Pra simplicidade, esta funcao devolve UMA root virtual:
|
|
13
|
+
* - Se existir claude-skills/plugins/PLUGIN/skills/, retorna a primeira (assume 1 plugin).
|
|
14
|
+
* - Senao, fallback pra claude-skills/skills/ (estrutura legada).
|
|
15
|
+
*/
|
|
16
|
+
export declare function getSkillsSourceDir(): string;
|
|
17
|
+
export declare function getClaudeSkillsDir(): string;
|
|
18
|
+
export interface SkillInfo {
|
|
19
|
+
name: string;
|
|
20
|
+
description: string;
|
|
21
|
+
version: string;
|
|
22
|
+
installed: boolean;
|
|
23
|
+
}
|
|
24
|
+
export declare function listAvailableSkills(): Promise<SkillInfo[]>;
|
|
25
|
+
export declare function runSkillsInstall(): Promise<void>;
|
|
26
|
+
export declare function runSkillsUpdate(): Promise<void>;
|
|
27
|
+
export declare function runSkillsList(): Promise<void>;
|
|
28
|
+
export declare function runSkillsUninstall(opts?: {
|
|
29
|
+
yes?: boolean;
|
|
30
|
+
}): Promise<void>;
|
|
31
|
+
export declare function runSdkInit(): Promise<void>;
|
|
32
|
+
export declare function runSdkTemplates(): Promise<void>;
|
|
33
|
+
export declare function runSdkAddTemplate(template: string, opts?: {
|
|
34
|
+
force?: boolean;
|
|
35
|
+
}): Promise<void>;
|
|
36
|
+
export declare function runMarketplaceBrowse(): Promise<void>;
|