@lenne.tech/cli 1.33.0 → 1.35.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 +6 -5
- package/build/commands/codex/codex.js +23 -0
- package/build/commands/codex/plugins.js +103 -0
- package/build/commands/codex/shortcuts.js +110 -0
- package/build/commands/config/validate.js +0 -4
- package/build/commands/deployment/create.js +218 -213
- package/build/commands/dev/init.js +2 -1
- package/build/commands/dev/status.js +2 -0
- package/build/commands/dev/test.js +12 -6
- package/build/commands/dev/up.js +17 -7
- package/build/commands/frontend/nuxt.js +4 -7
- package/build/commands/fullstack/add-api.js +6 -9
- package/build/commands/fullstack/add-app.js +5 -7
- package/build/commands/fullstack/init.js +34 -20
- package/build/commands/status.js +2 -0
- package/build/commands/ticket/list.js +2 -0
- package/build/commands/ticket/start.js +6 -4
- package/build/extensions/frontend-helper.js +44 -39
- package/build/extensions/server.js +354 -22
- package/build/lib/angular-environments.js +108 -0
- package/build/lib/codex-cli.js +56 -0
- package/build/lib/codex-plugin-utils.js +102 -0
- package/build/lib/dev-identity.js +38 -18
- package/build/lib/dev-package-manager.js +89 -0
- package/build/lib/dev-patches.js +4 -1
- package/build/lib/dev-project.js +20 -7
- package/build/lib/dev-state.js +17 -1
- package/build/lib/dev-test-session.js +61 -19
- package/build/lib/dev-ticket.js +12 -6
- package/build/lib/ensure-root-dockerignore.js +92 -0
- package/build/lib/fs-utils.js +19 -0
- package/build/lib/hoist-workspace-pnpm-config.js +2 -11
- package/build/lib/remove-nested-lockfiles.js +53 -0
- package/build/lib/turboops-config.js +93 -0
- package/build/lib/vendor-claude-md.js +7 -2
- package/build/lib/workspace-integration.js +96 -3
- package/build/templates/deployment/turboops.json.ejs +3 -0
- package/build/templates/vendor-scripts/migrate-store.js +25 -0
- package/docs/LT-ECOSYSTEM-GUIDE.md +1 -1
- package/docs/commands.md +30 -9
- package/docs/lt.config.md +9 -19
- package/package.json +1 -1
- package/build/templates/deployment/.github/workflows/pre-release.yml.ejs +0 -41
- package/build/templates/deployment/.github/workflows/release.yml.ejs +0 -41
- package/build/templates/deployment/.gitlab-ci.yml.ejs +0 -181
- package/build/templates/deployment/Dockerfile.app.ejs +0 -13
- package/build/templates/deployment/Dockerfile.ejs +0 -18
- package/build/templates/deployment/docker-compose.dev.yml.ejs +0 -99
- package/build/templates/deployment/docker-compose.prod.yml.ejs +0 -92
- package/build/templates/deployment/docker-compose.test.yml.ejs +0 -98
- package/build/templates/deployment/scripts/build-push.sh.ejs +0 -20
- package/build/templates/deployment/scripts/deploy.sh.ejs +0 -7
package/README.md
CHANGED
|
@@ -170,13 +170,14 @@ $ lt fullstack update
|
|
|
170
170
|
|
|
171
171
|
### Vendor-mode housekeeping
|
|
172
172
|
|
|
173
|
-
Vendor-mode projects
|
|
173
|
+
Vendor-mode projects carry no separate maintenance scripts under
|
|
174
|
+
`scripts/vendor/` anymore. The vendor-specific surface is now:
|
|
174
175
|
|
|
175
|
-
|
|
|
176
|
+
| Concern | Where | Invocation |
|
|
176
177
|
|---|---|---|
|
|
177
|
-
| `check
|
|
178
|
-
|
|
|
179
|
-
|
|
|
178
|
+
| Upstream freshness | Inline `check:vendor-freshness` script in `package.json` — reads the `src/core/VENDOR.md` baseline, compares against the npm registry, non-blocking | auto-invoked by `pnpm run check` / `check:fix` / `check:naf`, or `pnpm run check:vendor-freshness` |
|
|
179
|
+
| Sync from upstream | `nest-server-core-updater` Claude Code agent | `/lt-dev:backend:update-nest-server-core` |
|
|
180
|
+
| Propose local changes upstream | `nest-server-core-contributor` Claude Code agent | `/lt-dev:backend:contribute-nest-server-core` |
|
|
180
181
|
|
|
181
182
|
The vendor-mode baseline (upstream version + commit SHA) is recorded in
|
|
182
183
|
`src/core/VENDOR.md`. Log any substantial local patch there so the updater
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
/**
|
|
13
|
+
* Codex commands
|
|
14
|
+
*/
|
|
15
|
+
module.exports = {
|
|
16
|
+
alias: ['cx'],
|
|
17
|
+
description: 'Codex commands',
|
|
18
|
+
name: 'codex',
|
|
19
|
+
run: (toolbox) => __awaiter(void 0, void 0, void 0, function* () {
|
|
20
|
+
yield toolbox.helper.showMenu('codex');
|
|
21
|
+
return 'codex';
|
|
22
|
+
}),
|
|
23
|
+
};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const fs_1 = require("fs");
|
|
13
|
+
const path_1 = require("path");
|
|
14
|
+
const codex_cli_1 = require("../../lib/codex-cli");
|
|
15
|
+
const codex_plugin_utils_1 = require("../../lib/codex-plugin-utils");
|
|
16
|
+
const CODEX_PLUGIN_NAME = 'lt-dev';
|
|
17
|
+
/**
|
|
18
|
+
* Install/update lenne.tech Codex plugin, custom agents, and prompt wrappers.
|
|
19
|
+
*/
|
|
20
|
+
const PluginsCommand = {
|
|
21
|
+
alias: ['p'],
|
|
22
|
+
description: 'Install Codex plugins',
|
|
23
|
+
name: 'plugins',
|
|
24
|
+
run: (toolbox) => __awaiter(void 0, void 0, void 0, function* () {
|
|
25
|
+
const { helper, print: { error, info, spin, success, warning }, system, } = toolbox;
|
|
26
|
+
const timer = system.startTimer();
|
|
27
|
+
const marketplaceRoot = String(toolbox.parameters.options.path || codex_cli_1.DEFAULT_CODEX_MARKETPLACE_ROOT);
|
|
28
|
+
const pluginRoot = (0, path_1.join)(marketplaceRoot, 'plugins', CODEX_PLUGIN_NAME);
|
|
29
|
+
const marketplaceName = (0, codex_plugin_utils_1.readCodexMarketplaceName)(marketplaceRoot);
|
|
30
|
+
if (!marketplaceName) {
|
|
31
|
+
error(`Codex marketplace not found at ${marketplaceRoot}`);
|
|
32
|
+
info('');
|
|
33
|
+
info('Expected: .agents/plugins/marketplace.json');
|
|
34
|
+
info('Run this from a checkout that contains the generated codex marketplace, or pass --path=<marketplace-root>.');
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
if (!(0, fs_1.existsSync)(pluginRoot)) {
|
|
38
|
+
error(`Codex plugin not found: ${pluginRoot}`);
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
const cli = (0, codex_cli_1.findCodexCli)();
|
|
42
|
+
if (!cli) {
|
|
43
|
+
error('Codex CLI not found. Please install Codex first.');
|
|
44
|
+
info('');
|
|
45
|
+
info('Installation: https://developers.openai.com/codex');
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
const listSpinner = spin('Checking Codex marketplaces');
|
|
49
|
+
const listResult = (0, codex_cli_1.runCodexCommand)(cli, ['plugin', 'marketplace', 'list', '--json']);
|
|
50
|
+
const marketplaceConfigured = listResult.success &&
|
|
51
|
+
(listResult.output.includes(`"name": "${marketplaceName}"`) || listResult.output.includes(marketplaceRoot));
|
|
52
|
+
if (marketplaceConfigured) {
|
|
53
|
+
listSpinner.succeed(`Marketplace ${marketplaceName} already configured`);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
listSpinner.text = `Adding marketplace ${marketplaceName}`;
|
|
57
|
+
const addResult = (0, codex_cli_1.runCodexCommand)(cli, ['plugin', 'marketplace', 'add', marketplaceRoot, '--json']);
|
|
58
|
+
if (addResult.success || addResult.output.includes('already')) {
|
|
59
|
+
listSpinner.succeed(`Marketplace ${marketplaceName} added`);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
listSpinner.fail(`Failed to add marketplace ${marketplaceName}`);
|
|
63
|
+
error(addResult.output);
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const installSpinner = spin(`Installing/updating ${CODEX_PLUGIN_NAME}`);
|
|
68
|
+
const installResult = (0, codex_cli_1.runCodexCommand)(cli, ['plugin', 'add', `${CODEX_PLUGIN_NAME}@${marketplaceName}`, '--json']);
|
|
69
|
+
if (installResult.success || installResult.output.includes('already')) {
|
|
70
|
+
installSpinner.succeed(`${CODEX_PLUGIN_NAME} installed`);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
installSpinner.fail(`Failed to install ${CODEX_PLUGIN_NAME}`);
|
|
74
|
+
error(installResult.output);
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
const agentSpinner = spin('Installing Codex custom agents');
|
|
78
|
+
const agentCount = (0, codex_plugin_utils_1.installCodexAgents)(pluginRoot);
|
|
79
|
+
agentSpinner.succeed(`${agentCount} custom agents installed`);
|
|
80
|
+
const promptSpinner = spin('Installing Codex prompt wrappers');
|
|
81
|
+
const promptCount = (0, codex_plugin_utils_1.installCodexPrompts)(pluginRoot);
|
|
82
|
+
promptSpinner.succeed(`${promptCount} prompt wrappers installed`);
|
|
83
|
+
const contents = (0, codex_plugin_utils_1.readLocalCodexPluginContents)(pluginRoot);
|
|
84
|
+
info('');
|
|
85
|
+
success(`Codex setup completed in ${helper.msToMinutesAndSeconds(timer())}m.`);
|
|
86
|
+
info('');
|
|
87
|
+
info('Installed:');
|
|
88
|
+
info(` Plugin: ${CODEX_PLUGIN_NAME}@${marketplaceName}`);
|
|
89
|
+
info(` Skills (${contents.skills.length}): ${contents.skills.join(', ')}`);
|
|
90
|
+
info(` MCP Servers (${contents.mcpServers.length}): ${contents.mcpServers.join(', ')}`);
|
|
91
|
+
info(` Hooks: ${contents.hooks}`);
|
|
92
|
+
info(` Custom agents: ${agentCount}`);
|
|
93
|
+
info(` Prompt wrappers: ${promptCount}`);
|
|
94
|
+
info('');
|
|
95
|
+
warning('Restart Codex or start a new thread so new skills, agents, prompts, and MCP tools are loaded.');
|
|
96
|
+
info('Use former lt-dev commands via /prompts:lt-dev-... or by asking Codex to use the lt-dev command router.');
|
|
97
|
+
if (!toolbox.parameters.options.fromGluegunMenu) {
|
|
98
|
+
process.exit(0);
|
|
99
|
+
}
|
|
100
|
+
return 'codex plugins installed';
|
|
101
|
+
}),
|
|
102
|
+
};
|
|
103
|
+
exports.default = PluginsCommand;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const shell_config_1 = require("../../lib/shell-config");
|
|
13
|
+
const CODEX_SHORTCUTS = [
|
|
14
|
+
{
|
|
15
|
+
alias: 'x',
|
|
16
|
+
command: 'codex --sandbox workspace-write --ask-for-approval on-request',
|
|
17
|
+
description: 'Start new Codex session',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
alias: 'xr',
|
|
21
|
+
command: 'codex resume',
|
|
22
|
+
description: 'Select and resume previous Codex session',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
alias: 'xf',
|
|
26
|
+
command: 'LT_PLUGIN_HOOKS_SKIP=1 codex --sandbox workspace-write --ask-for-approval on-request',
|
|
27
|
+
description: 'Start Codex in fast mode (skip lenne.tech plugin detect hooks)',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
alias: 'xp',
|
|
31
|
+
command: 'lt codex plugins',
|
|
32
|
+
description: 'Install/update lenne.tech Codex plugin setup',
|
|
33
|
+
},
|
|
34
|
+
];
|
|
35
|
+
const ShortcutsCommand = {
|
|
36
|
+
alias: ['s'],
|
|
37
|
+
description: 'Install Codex shell shortcuts',
|
|
38
|
+
name: 'shortcuts',
|
|
39
|
+
run: (toolbox) => __awaiter(void 0, void 0, void 0, function* () {
|
|
40
|
+
const { print: { error, info, success }, } = toolbox;
|
|
41
|
+
const shellConfig = (0, shell_config_1.getPreferredShellConfig)();
|
|
42
|
+
if (!shellConfig) {
|
|
43
|
+
error('Could not detect shell configuration file.');
|
|
44
|
+
info('Supported shells: zsh, bash');
|
|
45
|
+
if (!toolbox.parameters.options.fromGluegunMenu) {
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
return 'shortcuts: no shell config found';
|
|
49
|
+
}
|
|
50
|
+
info(`Shell: ${shellConfig.shell}`);
|
|
51
|
+
info(`Config: ${shellConfig.path}`);
|
|
52
|
+
info('');
|
|
53
|
+
const existingAliases = [];
|
|
54
|
+
const missingAliases = [];
|
|
55
|
+
for (const shortcut of CODEX_SHORTCUTS) {
|
|
56
|
+
if ((0, shell_config_1.checkAliasInFile)(shellConfig.path, shortcut.alias)) {
|
|
57
|
+
existingAliases.push(shortcut);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
missingAliases.push(shortcut);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (existingAliases.length > 0) {
|
|
64
|
+
info('Already installed:');
|
|
65
|
+
for (const { alias, description } of existingAliases) {
|
|
66
|
+
info(` ${alias} - ${description}`);
|
|
67
|
+
}
|
|
68
|
+
info('');
|
|
69
|
+
}
|
|
70
|
+
if (missingAliases.length === 0) {
|
|
71
|
+
success('All Codex shortcuts are already installed!');
|
|
72
|
+
info('');
|
|
73
|
+
info('Available shortcuts:');
|
|
74
|
+
for (const { alias, command, description } of CODEX_SHORTCUTS) {
|
|
75
|
+
info(` ${alias} - ${description}`);
|
|
76
|
+
info(` ${command}`);
|
|
77
|
+
}
|
|
78
|
+
if (!toolbox.parameters.options.fromGluegunMenu) {
|
|
79
|
+
process.exit(0);
|
|
80
|
+
}
|
|
81
|
+
return 'shortcuts: already installed';
|
|
82
|
+
}
|
|
83
|
+
const added = (0, shell_config_1.addAliasBlockToShellConfig)(shellConfig.path, missingAliases, 'Codex shortcuts - Added by lenne.tech CLI');
|
|
84
|
+
if (added) {
|
|
85
|
+
info('');
|
|
86
|
+
success(`Added ${missingAliases.length} shortcut${missingAliases.length > 1 ? 's' : ''} to ${shellConfig.path}`);
|
|
87
|
+
info('');
|
|
88
|
+
info(`Run: source ${shellConfig.path}`);
|
|
89
|
+
info('Or restart your terminal to apply changes.');
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
error(`Failed to write to ${shellConfig.path}`);
|
|
93
|
+
info('');
|
|
94
|
+
info('To add manually, add these lines to your shell config:');
|
|
95
|
+
info('');
|
|
96
|
+
for (const { alias, command } of missingAliases) {
|
|
97
|
+
info(`alias ${alias}='${command}'`);
|
|
98
|
+
}
|
|
99
|
+
if (!toolbox.parameters.options.fromGluegunMenu) {
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
return 'shortcuts: write failed';
|
|
103
|
+
}
|
|
104
|
+
if (!toolbox.parameters.options.fromGluegunMenu) {
|
|
105
|
+
process.exit(0);
|
|
106
|
+
}
|
|
107
|
+
return `shortcuts: ${missingAliases.length} added`;
|
|
108
|
+
}),
|
|
109
|
+
};
|
|
110
|
+
exports.default = ShortcutsCommand;
|