@lenne.tech/cli 1.27.0 → 1.29.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/build/cli.js +7 -1
- package/build/commands/dev/doctor.js +27 -1
- package/build/commands/dev/down.js +22 -10
- package/build/commands/dev/status.js +4 -3
- package/build/commands/dev/test.js +12 -4
- package/build/commands/dev/up.js +90 -50
- package/build/commands/frontend/angular.js +48 -46
- package/build/commands/frontend/convert-mode.js +41 -39
- package/build/commands/frontend/nuxt.js +49 -47
- package/build/commands/fullstack/add-api.js +34 -32
- package/build/commands/fullstack/add-app.js +25 -23
- package/build/commands/fullstack/convert-mode.js +85 -65
- package/build/commands/fullstack/init.js +12 -0
- package/build/commands/fullstack/update.js +24 -0
- package/build/commands/server/add-property.js +42 -40
- package/build/commands/server/convert-mode.js +41 -39
- package/build/commands/server/create.js +65 -63
- package/build/commands/server/module.js +56 -54
- package/build/commands/server/object.js +42 -40
- package/build/commands/server/permissions.js +60 -58
- package/build/commands/ticket/list.js +78 -0
- package/build/commands/ticket/start.js +141 -0
- package/build/commands/ticket/stop.js +166 -0
- package/build/commands/ticket/switch.js +70 -0
- package/build/commands/ticket/test.js +80 -0
- package/build/commands/ticket/ticket.js +36 -0
- package/build/commands/tools/crawl.js +92 -90
- package/build/extensions/frontend-helper.js +8 -37
- package/build/extensions/server.js +8 -38
- package/build/lib/command-help.js +161 -0
- package/build/lib/dev-identity.js +18 -0
- package/build/lib/dev-patches.js +1 -1
- package/build/lib/dev-project.js +14 -0
- package/build/lib/dev-state.js +96 -0
- package/build/lib/dev-test-session.js +55 -35
- package/build/lib/dev-ticket.js +343 -0
- package/build/lib/vendor-claude-md.js +227 -0
- package/docs/lt-dev-ticket-workflow.html +603 -0
- package/docs/lt-dev-ticket-workflow.pdf +0 -0
- package/package.json +32 -1
|
@@ -9,6 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.help = void 0;
|
|
12
13
|
const workspace_integration_1 = require("../../lib/workspace-integration");
|
|
13
14
|
/**
|
|
14
15
|
* Create a new nuxt workspace
|
|
@@ -18,6 +19,53 @@ const workspace_integration_1 = require("../../lib/workspace-integration");
|
|
|
18
19
|
* a brand-new directory. Mirrors the same surface area as add-app where
|
|
19
20
|
* applicable so behaviour is consistent across the four flows.
|
|
20
21
|
*/
|
|
22
|
+
exports.help = {
|
|
23
|
+
aliases: ['n'],
|
|
24
|
+
configuration: 'commands.frontend.nuxt.*',
|
|
25
|
+
description: 'Create a new Nuxt workspace from nuxt-base-starter',
|
|
26
|
+
name: 'nuxt',
|
|
27
|
+
options: [
|
|
28
|
+
{ description: 'Workspace name', flag: '--name', required: false, type: 'string' },
|
|
29
|
+
{ description: 'Branch of nuxt-base-starter to clone', flag: '--branch', required: false, type: 'string' },
|
|
30
|
+
{ description: 'Copy from local template directory', flag: '--copy', required: false, type: 'string' },
|
|
31
|
+
{ description: 'Symlink to local template directory', flag: '--link', required: false, type: 'string' },
|
|
32
|
+
{
|
|
33
|
+
description: 'Frontend framework consumption mode',
|
|
34
|
+
flag: '--frontend-framework-mode',
|
|
35
|
+
required: false,
|
|
36
|
+
type: 'string',
|
|
37
|
+
values: ['npm', 'vendor'],
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
default: false,
|
|
41
|
+
description: 'Default branch to nuxt-base-starter#next (auth basePath aligned with experimental --next API)',
|
|
42
|
+
flag: '--next',
|
|
43
|
+
required: false,
|
|
44
|
+
type: 'boolean',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
default: false,
|
|
48
|
+
description: 'Print resolved plan and exit without making any changes',
|
|
49
|
+
flag: '--dry-run',
|
|
50
|
+
required: false,
|
|
51
|
+
type: 'boolean',
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
default: false,
|
|
55
|
+
description: 'Override the workspace-detection abort under --noConfirm',
|
|
56
|
+
flag: '--force',
|
|
57
|
+
required: false,
|
|
58
|
+
type: 'boolean',
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
default: false,
|
|
62
|
+
description: 'Skip all interactive prompts',
|
|
63
|
+
flag: '--noConfirm',
|
|
64
|
+
required: false,
|
|
65
|
+
type: 'boolean',
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
};
|
|
21
69
|
const NewCommand = {
|
|
22
70
|
alias: ['n'],
|
|
23
71
|
description: 'Creates a new nuxt workspace',
|
|
@@ -26,53 +74,7 @@ const NewCommand = {
|
|
|
26
74
|
run: (toolbox) => __awaiter(void 0, void 0, void 0, function* () {
|
|
27
75
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
28
76
|
const { config, filesystem, frontendHelper, helper, parameters, print: { error, info, spin }, prompt: { ask, confirm }, strings: { kebabCase }, system, } = toolbox;
|
|
29
|
-
if (toolbox.tools.helpJson({
|
|
30
|
-
aliases: ['n'],
|
|
31
|
-
configuration: 'commands.frontend.nuxt.*',
|
|
32
|
-
description: 'Create a new Nuxt workspace from nuxt-base-starter',
|
|
33
|
-
name: 'nuxt',
|
|
34
|
-
options: [
|
|
35
|
-
{ description: 'Workspace name', flag: '--name', required: false, type: 'string' },
|
|
36
|
-
{ description: 'Branch of nuxt-base-starter to clone', flag: '--branch', required: false, type: 'string' },
|
|
37
|
-
{ description: 'Copy from local template directory', flag: '--copy', required: false, type: 'string' },
|
|
38
|
-
{ description: 'Symlink to local template directory', flag: '--link', required: false, type: 'string' },
|
|
39
|
-
{
|
|
40
|
-
description: 'Frontend framework consumption mode',
|
|
41
|
-
flag: '--frontend-framework-mode',
|
|
42
|
-
required: false,
|
|
43
|
-
type: 'string',
|
|
44
|
-
values: ['npm', 'vendor'],
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
default: false,
|
|
48
|
-
description: 'Default branch to nuxt-base-starter#next (auth basePath aligned with experimental --next API)',
|
|
49
|
-
flag: '--next',
|
|
50
|
-
required: false,
|
|
51
|
-
type: 'boolean',
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
default: false,
|
|
55
|
-
description: 'Print resolved plan and exit without making any changes',
|
|
56
|
-
flag: '--dry-run',
|
|
57
|
-
required: false,
|
|
58
|
-
type: 'boolean',
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
default: false,
|
|
62
|
-
description: 'Override the workspace-detection abort under --noConfirm',
|
|
63
|
-
flag: '--force',
|
|
64
|
-
required: false,
|
|
65
|
-
type: 'boolean',
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
default: false,
|
|
69
|
-
description: 'Skip all interactive prompts',
|
|
70
|
-
flag: '--noConfirm',
|
|
71
|
-
required: false,
|
|
72
|
-
type: 'boolean',
|
|
73
|
-
},
|
|
74
|
-
],
|
|
75
|
-
})) {
|
|
77
|
+
if (toolbox.tools.helpJson(exports.help)) {
|
|
76
78
|
return;
|
|
77
79
|
}
|
|
78
80
|
// Load configuration. Nuxt-specific keys live under
|
|
@@ -9,6 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.help = void 0;
|
|
12
13
|
const hoist_workspace_pnpm_config_1 = require("../../lib/hoist-workspace-pnpm-config");
|
|
13
14
|
const workspace_integration_1 = require("../../lib/workspace-integration");
|
|
14
15
|
/**
|
|
@@ -20,6 +21,38 @@ const workspace_integration_1 = require("../../lib/workspace-integration");
|
|
|
20
21
|
* `lt fullstack init` workflow on a fresh directory instead, or remove
|
|
21
22
|
* the existing API first.
|
|
22
23
|
*/
|
|
24
|
+
exports.help = {
|
|
25
|
+
aliases: ['add-api'],
|
|
26
|
+
configuration: 'commands.fullstack.*',
|
|
27
|
+
description: 'Add a NestJS API to an existing fullstack workspace',
|
|
28
|
+
name: 'add-api',
|
|
29
|
+
options: [
|
|
30
|
+
{ description: 'API mode', flag: '--api-mode', type: 'string', values: ['Rest', 'GraphQL', 'Both'] },
|
|
31
|
+
{
|
|
32
|
+
description: 'Framework consumption mode',
|
|
33
|
+
flag: '--framework-mode',
|
|
34
|
+
type: 'string',
|
|
35
|
+
values: ['npm', 'vendor'],
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
description: 'Branch/tag/commit of upstream nest-server (vendor mode)',
|
|
39
|
+
flag: '--framework-upstream-branch',
|
|
40
|
+
type: 'string',
|
|
41
|
+
},
|
|
42
|
+
{ description: 'Branch of nest-server-starter to clone', flag: '--api-branch', type: 'string' },
|
|
43
|
+
{ description: 'Path to local API template to copy from', flag: '--api-copy', type: 'string' },
|
|
44
|
+
{ description: 'Path to local API template to symlink', flag: '--api-link', type: 'string' },
|
|
45
|
+
{
|
|
46
|
+
description: 'Use experimental nest-base template (Bun + Prisma + Postgres + Better-Auth)',
|
|
47
|
+
flag: '--next',
|
|
48
|
+
type: 'boolean',
|
|
49
|
+
},
|
|
50
|
+
{ description: 'Workspace root (defaults to cwd)', flag: '--workspace-dir', type: 'string' },
|
|
51
|
+
{ description: 'Skip install / format after API integration', flag: '--skip-install', type: 'boolean' },
|
|
52
|
+
{ description: 'Print resolved plan and exit without disk changes', flag: '--dry-run', type: 'boolean' },
|
|
53
|
+
{ description: 'Skip all interactive prompts', flag: '--noConfirm', type: 'boolean' },
|
|
54
|
+
],
|
|
55
|
+
};
|
|
23
56
|
const NewCommand = {
|
|
24
57
|
alias: ['add-api'],
|
|
25
58
|
description: 'Add API to fullstack workspace',
|
|
@@ -29,38 +62,7 @@ const NewCommand = {
|
|
|
29
62
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
30
63
|
const { config, filesystem, git, parameters, patching, print: { error, info, spin, success, warning }, prompt: { ask }, server, system, } = toolbox;
|
|
31
64
|
// Help-JSON support so AI agents can introspect the flags.
|
|
32
|
-
if (toolbox.tools.helpJson({
|
|
33
|
-
aliases: ['add-api'],
|
|
34
|
-
configuration: 'commands.fullstack.*',
|
|
35
|
-
description: 'Add a NestJS API to an existing fullstack workspace',
|
|
36
|
-
name: 'add-api',
|
|
37
|
-
options: [
|
|
38
|
-
{ description: 'API mode', flag: '--api-mode', type: 'string', values: ['Rest', 'GraphQL', 'Both'] },
|
|
39
|
-
{
|
|
40
|
-
description: 'Framework consumption mode',
|
|
41
|
-
flag: '--framework-mode',
|
|
42
|
-
type: 'string',
|
|
43
|
-
values: ['npm', 'vendor'],
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
description: 'Branch/tag/commit of upstream nest-server (vendor mode)',
|
|
47
|
-
flag: '--framework-upstream-branch',
|
|
48
|
-
type: 'string',
|
|
49
|
-
},
|
|
50
|
-
{ description: 'Branch of nest-server-starter to clone', flag: '--api-branch', type: 'string' },
|
|
51
|
-
{ description: 'Path to local API template to copy from', flag: '--api-copy', type: 'string' },
|
|
52
|
-
{ description: 'Path to local API template to symlink', flag: '--api-link', type: 'string' },
|
|
53
|
-
{
|
|
54
|
-
description: 'Use experimental nest-base template (Bun + Prisma + Postgres + Better-Auth)',
|
|
55
|
-
flag: '--next',
|
|
56
|
-
type: 'boolean',
|
|
57
|
-
},
|
|
58
|
-
{ description: 'Workspace root (defaults to cwd)', flag: '--workspace-dir', type: 'string' },
|
|
59
|
-
{ description: 'Skip install / format after API integration', flag: '--skip-install', type: 'boolean' },
|
|
60
|
-
{ description: 'Print resolved plan and exit without disk changes', flag: '--dry-run', type: 'boolean' },
|
|
61
|
-
{ description: 'Skip all interactive prompts', flag: '--noConfirm', type: 'boolean' },
|
|
62
|
-
],
|
|
63
|
-
})) {
|
|
65
|
+
if (toolbox.tools.helpJson(exports.help)) {
|
|
64
66
|
return;
|
|
65
67
|
}
|
|
66
68
|
const timer = system.startTimer();
|
|
@@ -9,6 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.help = void 0;
|
|
12
13
|
const hoist_workspace_pnpm_config_1 = require("../../lib/hoist-workspace-pnpm-config");
|
|
13
14
|
const workspace_integration_1 = require("../../lib/workspace-integration");
|
|
14
15
|
/**
|
|
@@ -19,6 +20,29 @@ const workspace_integration_1 = require("../../lib/workspace-integration");
|
|
|
19
20
|
*
|
|
20
21
|
* Refuses to run if `projects/app/` already exists.
|
|
21
22
|
*/
|
|
23
|
+
exports.help = {
|
|
24
|
+
aliases: ['add-app'],
|
|
25
|
+
configuration: 'commands.fullstack.*',
|
|
26
|
+
description: 'Add a frontend app to an existing fullstack workspace',
|
|
27
|
+
name: 'add-app',
|
|
28
|
+
options: [
|
|
29
|
+
{ description: 'Frontend framework', flag: '--frontend', type: 'string', values: ['nuxt', 'angular'] },
|
|
30
|
+
{
|
|
31
|
+
description: 'Frontend framework consumption mode',
|
|
32
|
+
flag: '--frontend-framework-mode',
|
|
33
|
+
type: 'string',
|
|
34
|
+
values: ['npm', 'vendor'],
|
|
35
|
+
},
|
|
36
|
+
{ description: 'Branch of the frontend starter to clone', flag: '--frontend-branch', type: 'string' },
|
|
37
|
+
{ description: 'Path to local frontend template to copy from', flag: '--frontend-copy', type: 'string' },
|
|
38
|
+
{ description: 'Path to local frontend template to symlink', flag: '--frontend-link', type: 'string' },
|
|
39
|
+
{ description: 'Use experimental nuxt-base-starter `next` branch', flag: '--next', type: 'boolean' },
|
|
40
|
+
{ description: 'Workspace root (defaults to cwd)', flag: '--workspace-dir', type: 'string' },
|
|
41
|
+
{ description: 'Skip install / format after app integration', flag: '--skip-install', type: 'boolean' },
|
|
42
|
+
{ description: 'Print resolved plan and exit without disk changes', flag: '--dry-run', type: 'boolean' },
|
|
43
|
+
{ description: 'Skip all interactive prompts', flag: '--noConfirm', type: 'boolean' },
|
|
44
|
+
],
|
|
45
|
+
};
|
|
22
46
|
const NewCommand = {
|
|
23
47
|
alias: ['add-app'],
|
|
24
48
|
description: 'Add app to fullstack workspace',
|
|
@@ -27,29 +51,7 @@ const NewCommand = {
|
|
|
27
51
|
run: (toolbox) => __awaiter(void 0, void 0, void 0, function* () {
|
|
28
52
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
29
53
|
const { config, filesystem, frontendHelper, git, parameters, print: { error, info, spin, success, warning }, prompt: { ask }, system, } = toolbox;
|
|
30
|
-
if (toolbox.tools.helpJson({
|
|
31
|
-
aliases: ['add-app'],
|
|
32
|
-
configuration: 'commands.fullstack.*',
|
|
33
|
-
description: 'Add a frontend app to an existing fullstack workspace',
|
|
34
|
-
name: 'add-app',
|
|
35
|
-
options: [
|
|
36
|
-
{ description: 'Frontend framework', flag: '--frontend', type: 'string', values: ['nuxt', 'angular'] },
|
|
37
|
-
{
|
|
38
|
-
description: 'Frontend framework consumption mode',
|
|
39
|
-
flag: '--frontend-framework-mode',
|
|
40
|
-
type: 'string',
|
|
41
|
-
values: ['npm', 'vendor'],
|
|
42
|
-
},
|
|
43
|
-
{ description: 'Branch of the frontend starter to clone', flag: '--frontend-branch', type: 'string' },
|
|
44
|
-
{ description: 'Path to local frontend template to copy from', flag: '--frontend-copy', type: 'string' },
|
|
45
|
-
{ description: 'Path to local frontend template to symlink', flag: '--frontend-link', type: 'string' },
|
|
46
|
-
{ description: 'Use experimental nuxt-base-starter `next` branch', flag: '--next', type: 'boolean' },
|
|
47
|
-
{ description: 'Workspace root (defaults to cwd)', flag: '--workspace-dir', type: 'string' },
|
|
48
|
-
{ description: 'Skip install / format after app integration', flag: '--skip-install', type: 'boolean' },
|
|
49
|
-
{ description: 'Print resolved plan and exit without disk changes', flag: '--dry-run', type: 'boolean' },
|
|
50
|
-
{ description: 'Skip all interactive prompts', flag: '--noConfirm', type: 'boolean' },
|
|
51
|
-
],
|
|
52
|
-
})) {
|
|
54
|
+
if (toolbox.tools.helpJson(exports.help)) {
|
|
53
55
|
return;
|
|
54
56
|
}
|
|
55
57
|
const timer = system.startTimer();
|
|
@@ -9,9 +9,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.help = void 0;
|
|
12
13
|
const path_1 = require("path");
|
|
13
14
|
const framework_detection_1 = require("../../lib/framework-detection");
|
|
14
15
|
const frontend_framework_detection_1 = require("../../lib/frontend-framework-detection");
|
|
16
|
+
const vendor_claude_md_1 = require("../../lib/vendor-claude-md");
|
|
15
17
|
/**
|
|
16
18
|
* Convert both backend and frontend of a fullstack monorepo between
|
|
17
19
|
* npm mode and vendor mode in a single command.
|
|
@@ -26,6 +28,71 @@ const frontend_framework_detection_1 = require("../../lib/frontend-framework-det
|
|
|
26
28
|
* Orchestrates `lt server convert-mode` + `lt frontend convert-mode` with
|
|
27
29
|
* auto-detection of `projects/api/` and `projects/app/` subdirectories.
|
|
28
30
|
*/
|
|
31
|
+
exports.help = {
|
|
32
|
+
description: 'Convert fullstack monorepo (backend + frontend) between npm and vendor modes',
|
|
33
|
+
name: 'convert-mode',
|
|
34
|
+
options: [
|
|
35
|
+
{
|
|
36
|
+
description: 'Target mode',
|
|
37
|
+
flag: '--to',
|
|
38
|
+
required: true,
|
|
39
|
+
type: 'string',
|
|
40
|
+
values: ['vendor', 'npm'],
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
description: 'Backend upstream branch/tag (only with --to vendor, e.g. "11.24.3")',
|
|
44
|
+
flag: '--framework-upstream-branch',
|
|
45
|
+
required: false,
|
|
46
|
+
type: 'string',
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
description: 'Frontend upstream branch/tag (only with --to vendor, e.g. "1.5.3")',
|
|
50
|
+
flag: '--frontend-framework-upstream-branch',
|
|
51
|
+
required: false,
|
|
52
|
+
type: 'string',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
description: 'Backend version to install (only with --to npm, default: from VENDOR.md baseline)',
|
|
56
|
+
flag: '--framework-version',
|
|
57
|
+
required: false,
|
|
58
|
+
type: 'string',
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
description: 'Frontend version to install (only with --to npm, default: from VENDOR.md baseline)',
|
|
62
|
+
flag: '--frontend-framework-version',
|
|
63
|
+
required: false,
|
|
64
|
+
type: 'string',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
default: false,
|
|
68
|
+
description: 'Skip backend conversion',
|
|
69
|
+
flag: '--skip-backend',
|
|
70
|
+
required: false,
|
|
71
|
+
type: 'boolean',
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
default: false,
|
|
75
|
+
description: 'Skip frontend conversion',
|
|
76
|
+
flag: '--skip-frontend',
|
|
77
|
+
required: false,
|
|
78
|
+
type: 'boolean',
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
default: false,
|
|
82
|
+
description: 'Show the resolved plan without making any changes',
|
|
83
|
+
flag: '--dry-run',
|
|
84
|
+
required: false,
|
|
85
|
+
type: 'boolean',
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
default: false,
|
|
89
|
+
description: 'Skip confirmation prompt',
|
|
90
|
+
flag: '--noConfirm',
|
|
91
|
+
required: false,
|
|
92
|
+
type: 'boolean',
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
};
|
|
29
96
|
const ConvertModeCommand = {
|
|
30
97
|
description: 'Convert fullstack monorepo between npm and vendor modes',
|
|
31
98
|
hidden: false,
|
|
@@ -33,71 +100,7 @@ const ConvertModeCommand = {
|
|
|
33
100
|
run: (toolbox) => __awaiter(void 0, void 0, void 0, function* () {
|
|
34
101
|
const { filesystem, frontendHelper, parameters, print: { colors, error, info, spin, success, warning }, prompt: { confirm }, server, } = toolbox;
|
|
35
102
|
// Handle --help-json flag
|
|
36
|
-
if (toolbox.tools.helpJson({
|
|
37
|
-
description: 'Convert fullstack monorepo (backend + frontend) between npm and vendor modes',
|
|
38
|
-
name: 'convert-mode',
|
|
39
|
-
options: [
|
|
40
|
-
{
|
|
41
|
-
description: 'Target mode',
|
|
42
|
-
flag: '--to',
|
|
43
|
-
required: true,
|
|
44
|
-
type: 'string',
|
|
45
|
-
values: ['vendor', 'npm'],
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
description: 'Backend upstream branch/tag (only with --to vendor, e.g. "11.24.3")',
|
|
49
|
-
flag: '--framework-upstream-branch',
|
|
50
|
-
required: false,
|
|
51
|
-
type: 'string',
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
description: 'Frontend upstream branch/tag (only with --to vendor, e.g. "1.5.3")',
|
|
55
|
-
flag: '--frontend-framework-upstream-branch',
|
|
56
|
-
required: false,
|
|
57
|
-
type: 'string',
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
description: 'Backend version to install (only with --to npm, default: from VENDOR.md baseline)',
|
|
61
|
-
flag: '--framework-version',
|
|
62
|
-
required: false,
|
|
63
|
-
type: 'string',
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
description: 'Frontend version to install (only with --to npm, default: from VENDOR.md baseline)',
|
|
67
|
-
flag: '--frontend-framework-version',
|
|
68
|
-
required: false,
|
|
69
|
-
type: 'string',
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
default: false,
|
|
73
|
-
description: 'Skip backend conversion',
|
|
74
|
-
flag: '--skip-backend',
|
|
75
|
-
required: false,
|
|
76
|
-
type: 'boolean',
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
default: false,
|
|
80
|
-
description: 'Skip frontend conversion',
|
|
81
|
-
flag: '--skip-frontend',
|
|
82
|
-
required: false,
|
|
83
|
-
type: 'boolean',
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
default: false,
|
|
87
|
-
description: 'Show the resolved plan without making any changes',
|
|
88
|
-
flag: '--dry-run',
|
|
89
|
-
required: false,
|
|
90
|
-
type: 'boolean',
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
default: false,
|
|
94
|
-
description: 'Skip confirmation prompt',
|
|
95
|
-
flag: '--noConfirm',
|
|
96
|
-
required: false,
|
|
97
|
-
type: 'boolean',
|
|
98
|
-
},
|
|
99
|
-
],
|
|
100
|
-
})) {
|
|
103
|
+
if (toolbox.tools.helpJson(exports.help)) {
|
|
101
104
|
return;
|
|
102
105
|
}
|
|
103
106
|
const targetMode = parameters.options.to;
|
|
@@ -348,6 +351,23 @@ const ConvertModeCommand = {
|
|
|
348
351
|
}
|
|
349
352
|
info('');
|
|
350
353
|
success('All conversions completed successfully.');
|
|
354
|
+
// ── Sync vendor notice blocks, including the monorepo root CLAUDE.md ───
|
|
355
|
+
// The per-subproject CLAUDE.md blocks are written by the server/frontend
|
|
356
|
+
// converters; this additionally maintains the workspace root CLAUDE.md —
|
|
357
|
+
// the entry point Claude reads first — and keeps everything idempotent.
|
|
358
|
+
const backendVendorNow = backendDir ? (0, framework_detection_1.detectFrameworkMode)(backendDir) === 'vendor' : false;
|
|
359
|
+
const frontendVendorNow = frontendDir ? (0, frontend_framework_detection_1.detectFrontendFrameworkMode)(frontendDir) === 'vendor' : false;
|
|
360
|
+
const changedClaudeMd = (0, vendor_claude_md_1.healVendorClaudeMd)(filesystem, {
|
|
361
|
+
apiDir: backendDir,
|
|
362
|
+
appDir: frontendDir,
|
|
363
|
+
backendVendor: backendVendorNow,
|
|
364
|
+
frontendVendor: frontendVendorNow,
|
|
365
|
+
workspaceRoot: cwd,
|
|
366
|
+
});
|
|
367
|
+
if (changedClaudeMd.length > 0) {
|
|
368
|
+
info('');
|
|
369
|
+
success(`Synced vendor notice in ${changedClaudeMd.length} CLAUDE.md file(s) (incl. monorepo root).`);
|
|
370
|
+
}
|
|
351
371
|
info('');
|
|
352
372
|
info(colors.bold('Next steps:'));
|
|
353
373
|
info(' 1. Run: pnpm install (from monorepo root)');
|
|
@@ -18,6 +18,7 @@ const dev_migrate_helper_1 = require("../../lib/dev-migrate-helper");
|
|
|
18
18
|
const dev_project_1 = require("../../lib/dev-project");
|
|
19
19
|
const hoist_workspace_pnpm_config_1 = require("../../lib/hoist-workspace-pnpm-config");
|
|
20
20
|
const package_name_1 = require("../../lib/package-name");
|
|
21
|
+
const vendor_claude_md_1 = require("../../lib/vendor-claude-md");
|
|
21
22
|
const workspace_integration_1 = require("../../lib/workspace-integration");
|
|
22
23
|
const add_api_1 = __importDefault(require("./add-api"));
|
|
23
24
|
const add_app_1 = __importDefault(require("./add-app"));
|
|
@@ -641,6 +642,17 @@ const NewCommand = {
|
|
|
641
642
|
if (!experimental && isNuxt && filesystem.isDirectory(`${projectDir}/projects/app`)) {
|
|
642
643
|
yield toolbox.apiMode.formatProject(`${projectDir}/projects/app`);
|
|
643
644
|
}
|
|
645
|
+
// Sync the vendor-mode notice blocks across all CLAUDE.md files,
|
|
646
|
+
// including the monorepo root — so a freshly scaffolded vendor project
|
|
647
|
+
// tells Claude (and humans) how to update/contribute the vendored core
|
|
648
|
+
// from the very first commit. Idempotent / no-op for npm-mode projects.
|
|
649
|
+
(0, vendor_claude_md_1.healVendorClaudeMd)(filesystem, {
|
|
650
|
+
apiDir: `${projectDir}/projects/api`,
|
|
651
|
+
appDir: `${projectDir}/projects/app`,
|
|
652
|
+
backendVendor: frameworkMode === 'vendor',
|
|
653
|
+
frontendVendor: frontendFrameworkMode === 'vendor',
|
|
654
|
+
workspaceRoot: projectDir,
|
|
655
|
+
});
|
|
644
656
|
// Create initial commit after everything is set up
|
|
645
657
|
try {
|
|
646
658
|
yield system.run(`cd ${projectDir} && git add . && git commit -m "Initial commit"`);
|
|
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
const path_1 = require("path");
|
|
13
13
|
const framework_detection_1 = require("../../lib/framework-detection");
|
|
14
14
|
const frontend_framework_detection_1 = require("../../lib/frontend-framework-detection");
|
|
15
|
+
const vendor_claude_md_1 = require("../../lib/vendor-claude-md");
|
|
15
16
|
/**
|
|
16
17
|
* Update a fullstack workspace — mode-aware.
|
|
17
18
|
*
|
|
@@ -161,6 +162,29 @@ const NewCommand = {
|
|
|
161
162
|
info('');
|
|
162
163
|
}
|
|
163
164
|
}
|
|
165
|
+
// ── Self-heal: sync the vendor-mode notice blocks in all CLAUDE.md ────
|
|
166
|
+
//
|
|
167
|
+
// `lt fullstack update` doubles as a doc-sync: it (re)writes the vendor
|
|
168
|
+
// notice blocks so pre-existing or drifted projects gain the correct
|
|
169
|
+
// pointers — backend `projects/api/CLAUDE.md`, frontend
|
|
170
|
+
// `projects/app/CLAUDE.md`, and the monorepo root `CLAUDE.md` (the entry
|
|
171
|
+
// point Claude reads first). Idempotent: a no-op when already correct.
|
|
172
|
+
const frontendModeForHeal = appDir ? (0, frontend_framework_detection_1.detectFrontendFrameworkMode)(appDir) : undefined;
|
|
173
|
+
const isWorkspace = apiDir !== cwd || (!!appDir && appDir !== cwd);
|
|
174
|
+
const changedClaudeMd = (0, vendor_claude_md_1.healVendorClaudeMd)(filesystem, {
|
|
175
|
+
apiDir,
|
|
176
|
+
appDir,
|
|
177
|
+
backendVendor: mode === 'vendor',
|
|
178
|
+
frontendVendor: frontendModeForHeal === 'vendor',
|
|
179
|
+
workspaceRoot: isWorkspace ? cwd : undefined,
|
|
180
|
+
});
|
|
181
|
+
if (changedClaudeMd.length > 0) {
|
|
182
|
+
info('');
|
|
183
|
+
success(` Synced vendor notice in ${changedClaudeMd.length} CLAUDE.md file(s):`);
|
|
184
|
+
for (const changedPath of changedClaudeMd) {
|
|
185
|
+
info(` ${changedPath}`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
164
188
|
info('');
|
|
165
189
|
info(colors.bold('For a comprehensive update of everything, use:'));
|
|
166
190
|
info('');
|
|
@@ -12,6 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.help = void 0;
|
|
15
16
|
const path_1 = require("path");
|
|
16
17
|
const ts_morph_1 = require("ts-morph");
|
|
17
18
|
const framework_detection_1 = require("../../lib/framework-detection");
|
|
@@ -20,6 +21,46 @@ const object_1 = __importDefault(require("./object"));
|
|
|
20
21
|
/**
|
|
21
22
|
* Add property to module or object
|
|
22
23
|
*/
|
|
24
|
+
exports.help = {
|
|
25
|
+
aliases: ['ap'],
|
|
26
|
+
configuration: 'commands.server.addProp.*',
|
|
27
|
+
description: 'Add property to module/object',
|
|
28
|
+
name: 'addProp',
|
|
29
|
+
options: [
|
|
30
|
+
{
|
|
31
|
+
description: 'Target type to update',
|
|
32
|
+
flag: '--type',
|
|
33
|
+
required: true,
|
|
34
|
+
type: 'string',
|
|
35
|
+
values: ['Module', 'Object'],
|
|
36
|
+
},
|
|
37
|
+
{ description: 'Name of the module or object to update', flag: '--element', required: true, type: 'string' },
|
|
38
|
+
{
|
|
39
|
+
default: false,
|
|
40
|
+
description: 'Skip lint fix after update',
|
|
41
|
+
flag: '--skipLint',
|
|
42
|
+
required: false,
|
|
43
|
+
type: 'boolean',
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
propertyFlags: {
|
|
47
|
+
attributes: [
|
|
48
|
+
{ description: 'Property name', name: 'name', type: 'string' },
|
|
49
|
+
{
|
|
50
|
+
description: 'Property type',
|
|
51
|
+
name: 'type',
|
|
52
|
+
type: 'string',
|
|
53
|
+
values: ['string', 'number', 'boolean', 'bigint', 'Date', 'ObjectId', 'Json'],
|
|
54
|
+
},
|
|
55
|
+
{ description: 'Optional field', name: 'nullable', type: 'boolean' },
|
|
56
|
+
{ description: 'Array of this type', name: 'array', type: 'boolean' },
|
|
57
|
+
{ description: 'Enum type reference', name: 'enum', type: 'string' },
|
|
58
|
+
{ description: 'Embedded object/schema reference', name: 'schema', type: 'string' },
|
|
59
|
+
{ description: 'Reference module for ObjectId fields', name: 'reference', type: 'string' },
|
|
60
|
+
],
|
|
61
|
+
pattern: '--prop-<attribute>-<index>',
|
|
62
|
+
},
|
|
63
|
+
};
|
|
23
64
|
const NewCommand = {
|
|
24
65
|
alias: ['ap'],
|
|
25
66
|
description: 'Add property to module/object',
|
|
@@ -32,46 +73,7 @@ const NewCommand = {
|
|
|
32
73
|
// Retrieve the tools we need
|
|
33
74
|
const { config, filesystem, parameters, print: { divider, error, info, spin, success }, prompt: { ask, confirm }, server, strings: { pascalCase }, system, } = toolbox;
|
|
34
75
|
// Handle --help-json flag
|
|
35
|
-
if (toolbox.tools.helpJson({
|
|
36
|
-
aliases: ['ap'],
|
|
37
|
-
configuration: 'commands.server.addProp.*',
|
|
38
|
-
description: 'Add property to module/object',
|
|
39
|
-
name: 'addProp',
|
|
40
|
-
options: [
|
|
41
|
-
{
|
|
42
|
-
description: 'Target type to update',
|
|
43
|
-
flag: '--type',
|
|
44
|
-
required: true,
|
|
45
|
-
type: 'string',
|
|
46
|
-
values: ['Module', 'Object'],
|
|
47
|
-
},
|
|
48
|
-
{ description: 'Name of the module or object to update', flag: '--element', required: true, type: 'string' },
|
|
49
|
-
{
|
|
50
|
-
default: false,
|
|
51
|
-
description: 'Skip lint fix after update',
|
|
52
|
-
flag: '--skipLint',
|
|
53
|
-
required: false,
|
|
54
|
-
type: 'boolean',
|
|
55
|
-
},
|
|
56
|
-
],
|
|
57
|
-
propertyFlags: {
|
|
58
|
-
attributes: [
|
|
59
|
-
{ description: 'Property name', name: 'name', type: 'string' },
|
|
60
|
-
{
|
|
61
|
-
description: 'Property type',
|
|
62
|
-
name: 'type',
|
|
63
|
-
type: 'string',
|
|
64
|
-
values: ['string', 'number', 'boolean', 'bigint', 'Date', 'ObjectId', 'Json'],
|
|
65
|
-
},
|
|
66
|
-
{ description: 'Optional field', name: 'nullable', type: 'boolean' },
|
|
67
|
-
{ description: 'Array of this type', name: 'array', type: 'boolean' },
|
|
68
|
-
{ description: 'Enum type reference', name: 'enum', type: 'string' },
|
|
69
|
-
{ description: 'Embedded object/schema reference', name: 'schema', type: 'string' },
|
|
70
|
-
{ description: 'Reference module for ObjectId fields', name: 'reference', type: 'string' },
|
|
71
|
-
],
|
|
72
|
-
pattern: '--prop-<attribute>-<index>',
|
|
73
|
-
},
|
|
74
|
-
})) {
|
|
76
|
+
if (toolbox.tools.helpJson(exports.help)) {
|
|
75
77
|
return;
|
|
76
78
|
}
|
|
77
79
|
const argProps = Object.keys(toolbox.parameters.options || {}).filter((key) => key.startsWith('prop'));
|