@jay-framework/jay-stack-cli 0.22.0 → 0.22.2

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.
@@ -1,28 +1,26 @@
1
1
  # CLI Commands Reference
2
2
 
3
- ## jay-stack setup
3
+ ## jay-stack-cli setup
4
4
 
5
- Run plugin setup. Plugins can create configuration files, generate reference data, and validate their prerequisites.
5
+ Run plugin setup. Plugins create configuration files, prompt for credentials, and validate services.
6
6
 
7
7
  ```bash
8
- # Run setup for all installed plugins
9
- jay-stack setup
8
+ # Run setup for all installed plugins (interactive — may prompt for input)
9
+ jay-stack-cli setup
10
10
 
11
11
  # Run setup for a specific plugin
12
- jay-stack setup wix-stores
12
+ jay-stack-cli setup wix-stores
13
13
 
14
14
  # Re-run setup (e.g., after config change)
15
- jay-stack setup wix-data --force
16
- ```
17
-
18
- Plugins declare their setup handler in `plugin.yaml`. Setup does two things:
15
+ jay-stack-cli setup --force
19
16
 
20
- 1. **Config templates**: Creates `config/<plugin>.yaml` with placeholder credentials if missing
21
- 2. **Credential validation**: Attempts to initialize services, reports success or failure
17
+ # Non-interactive mode (creates config templates without prompting)
18
+ jay-stack-cli setup --no-interactive
19
+ ```
22
20
 
23
- Reference data (product catalogs, collection schemas) is generated by `jay-stack agent-kit`, not by setup.
21
+ Setup is **interactive by default** plugins may prompt for API keys and credentials. Use `--no-interactive` in CI/scripts.
24
22
 
25
- Run this after installing new plugins, before `jay-stack agent-kit`.
23
+ Run this after installing new plugins, before `jay-stack-cli agent-kit`.
26
24
 
27
25
  ## jay-stack agent-kit
28
26
 
@@ -1,28 +1,34 @@
1
1
  # CLI Commands Reference
2
2
 
3
- ## jay-stack setup
3
+ ## jay-stack-cli setup
4
4
 
5
- Run plugin setup. Plugins can create configuration files, generate reference data, and validate their prerequisites.
5
+ Run plugin setup. Plugins can create configuration files, prompt for credentials, and validate their prerequisites.
6
6
 
7
7
  ```bash
8
- # Run setup for all installed plugins
9
- jay-stack setup
8
+ # Run setup for all installed plugins (interactive — may prompt for input)
9
+ jay-stack-cli setup
10
10
 
11
11
  # Run setup for a specific plugin
12
- jay-stack setup wix-stores
12
+ jay-stack-cli setup wix-stores
13
13
 
14
14
  # Re-run setup (e.g., after config change)
15
- jay-stack setup wix-data --force
15
+ jay-stack-cli setup wix-data --force
16
+
17
+ # Non-interactive mode (CI/scripts — creates config templates without prompting)
18
+ jay-stack-cli setup --no-interactive
16
19
  ```
17
20
 
18
- Plugins declare their setup handler in `plugin.yaml`. Setup does two things:
21
+ Setup is **interactive by default** plugins can prompt for API keys, credentials, and configuration choices. In non-interactive mode (`--no-interactive`), prompts are skipped and plugins create config templates with placeholders instead.
22
+
23
+ Plugins declare their setup handler in `plugin.yaml`. Setup does three things:
19
24
 
20
- 1. **Config templates**: Creates `config/<plugin>.yaml` with placeholder credentials if missing
21
- 2. **Credential validation**: Attempts to initialize services, reports success or failure
25
+ 1. **Config templates**: Creates `config/<plugin>.yaml` with credentials (interactive) or placeholders (non-interactive)
26
+ 2. **Credential prompts**: Asks for API keys and configuration when running interactively
27
+ 3. **Service validation**: Attempts to initialize services, reports success or failure
22
28
 
23
- Reference data (product catalogs, collection schemas) is generated by `jay-stack agent-kit`, not by setup.
29
+ Reference data (product catalogs, collection schemas) is generated by `jay-stack-cli agent-kit`, not by setup.
24
30
 
25
- Run this after installing new plugins, before `jay-stack agent-kit`.
31
+ Run this after installing new plugins, before `jay-stack-cli agent-kit`.
26
32
 
27
33
  ## jay-stack agent-kit
28
34
 
@@ -14,6 +14,56 @@ The devops role handles the production lifecycle: building artifacts, configurin
14
14
  4. **Invalidate** — rebuild specific pages when data changes
15
15
  5. **Admin** — run plugin CLI commands via `jay-stack run <plugin>/<command>` (media upload, data sync, cache purge)
16
16
 
17
+ ## Plugin Setup
18
+
19
+ Plugins may need credentials or configuration before they can run. The setup command handles this.
20
+
21
+ ```bash
22
+ # Default (non-interactive) — exits with structured output if input is needed
23
+ jay-stack-cli setup
24
+
25
+ # Interactive — prompts for credentials via terminal
26
+ jay-stack-cli setup --interactive
27
+
28
+ # With pre-provided answers (for automation)
29
+ jay-stack-cli setup --answers answers.yaml
30
+ ```
31
+
32
+ ### Automated setup (CI / agents)
33
+
34
+ When running `jay-stack-cli setup` without `--interactive`, plugins that need user input will exit with structured YAML output:
35
+
36
+ ```yaml
37
+ setup-needs-answer:
38
+ plugin: wix-server-client
39
+ key: api-key
40
+ type: input
41
+ message: 'Enter your API key'
42
+ ```
43
+
44
+ To provide the answer, create a YAML file and re-run:
45
+
46
+ ```yaml
47
+ # answers.yaml
48
+ api-key: 'IST.abc123...'
49
+ ```
50
+
51
+ ```bash
52
+ jay-stack-cli setup --answers answers.yaml
53
+ ```
54
+
55
+ Repeat until all plugins report `configured`. The flow is iterative — each run may reveal the next question.
56
+
57
+ ### Setup order
58
+
59
+ Run setup **before** agent-kit and build:
60
+
61
+ ```bash
62
+ jay-stack-cli setup # 1. Configure plugins
63
+ jay-stack-cli agent-kit # 2. Generate contracts and discovery data
64
+ jay-stack-cli build # 3. Production build
65
+ ```
66
+
17
67
  ## Guides
18
68
 
19
69
  | File | Topic |
@@ -30,10 +30,12 @@ description: Validate credentials and install config # optional, top-level
30
30
 
31
31
  ## Writing a Setup Handler
32
32
 
33
- The setup handler creates config files and validates services. It receives a `PluginSetupContext` and returns a `PluginSetupResult`.
33
+ The setup handler creates config files, validates services, and can prompt the user for credentials. It receives a `PluginSetupContext` and returns a `PluginSetupResult`.
34
34
 
35
35
  **Do not** write add-menu catalogs in setup — use the agent-kit handler.
36
36
 
37
+ ### Basic setup (non-interactive)
38
+
37
39
  ```typescript
38
40
  import type { PluginSetupContext, PluginSetupResult } from '@jay-framework/stack-server-runtime';
39
41
  import fs from 'node:fs';
@@ -49,7 +51,7 @@ export async function setupMyPlugin(ctx: PluginSetupContext): Promise<PluginSetu
49
51
 
50
52
  if (!fs.existsSync(configPath) || ctx.force) {
51
53
  fs.mkdirSync(ctx.configDir, { recursive: true });
52
- fs.writeFileSync(configPath, '# My Plugin config\n', 'utf-8');
54
+ fs.writeFileSync(configPath, '# My Plugin config\napiKey: "<your-api-key>"\n', 'utf-8');
53
55
  configCreated.push('config/.my-plugin.yaml');
54
56
  }
55
57
 
@@ -64,16 +66,124 @@ export async function setupMyPlugin(ctx: PluginSetupContext): Promise<PluginSetu
64
66
  }
65
67
  ```
66
68
 
69
+ ### Interactive setup (with prompts)
70
+
71
+ When the setup handler needs user input (API keys, credentials, configuration choices), use `ctx.prompt`:
72
+
73
+ ```typescript
74
+ export async function setupMyPlugin(ctx: PluginSetupContext): Promise<PluginSetupResult> {
75
+ const configPath = path.join(ctx.configDir, '.my-plugin.yaml');
76
+
77
+ // Already configured — skip unless --force
78
+ if (fs.existsSync(configPath) && !ctx.force) {
79
+ return { status: 'configured', message: 'Already configured' };
80
+ }
81
+
82
+ // In non-interactive mode, create a template and ask the user to fill it in later
83
+ if (!ctx.interactive) {
84
+ fs.mkdirSync(ctx.configDir, { recursive: true });
85
+ fs.writeFileSync(configPath, 'apiKey: "<your-api-key>"\n', 'utf-8');
86
+ return {
87
+ status: 'needs-config',
88
+ configCreated: ['config/.my-plugin.yaml'],
89
+ message: 'Run `jay-stack-cli setup` interactively to enter your API key',
90
+ };
91
+ }
92
+
93
+ // Interactive mode — prompt the user
94
+ const apiKey = await ctx.prompt.input({
95
+ message: 'Enter your API key (create one at https://example.com/api-keys):',
96
+ validate: (v) => (v.trim() ? true : 'API key is required'),
97
+ });
98
+
99
+ const region = await ctx.prompt.select({
100
+ message: 'Select your region:',
101
+ choices: [
102
+ { name: 'US East', value: 'us-east' },
103
+ { name: 'EU West', value: 'eu-west' },
104
+ ],
105
+ });
106
+
107
+ fs.mkdirSync(ctx.configDir, { recursive: true });
108
+ fs.writeFileSync(configPath, `apiKey: "${apiKey.trim()}"\nregion: ${region}\n`, 'utf-8');
109
+
110
+ return {
111
+ status: 'configured',
112
+ configCreated: ['config/.my-plugin.yaml'],
113
+ message: 'Credentials configured successfully',
114
+ };
115
+ }
116
+ ```
117
+
118
+ ### Setup modes
119
+
120
+ Setup runs in three modes:
121
+
122
+ | Mode | Command | `ctx.interactive` | `ctx.prompt` behavior |
123
+ | ----------------------------- | ----------------------------------------- | ----------------- | ----------------------------------------------------- |
124
+ | **Default** (agents, CI) | `jay-stack-cli setup` | `false` | Throws `SetupNeedsAnswerError` with structured output |
125
+ | **Interactive** (humans) | `jay-stack-cli setup --interactive` | `true` | Prompts via terminal |
126
+ | **Answers file** (automation) | `jay-stack-cli setup --answers file.yaml` | `false` | Reads from file, throws if missing |
127
+
128
+ In default mode, when a prompt has no answer, the CLI exits with structured YAML telling the caller what's needed. Agents can then provide the answer via `--answers` and re-run.
129
+
130
+ ### Idempotency requirement
131
+
132
+ Setup handlers **must be idempotent** — re-running with the same answers must produce the same result without side effects. This is critical because:
133
+
134
+ - Agents re-run setup iteratively as they provide answers one at a time
135
+ - Users re-run setup after fixing credentials
136
+ - CI pipelines may run setup on every deploy
137
+
138
+ **Rules:**
139
+
140
+ 1. Check if config already exists before creating it — skip if present (unless `ctx.force`)
141
+ 2. Check if credentials are already valid before prompting — skip if configured
142
+ 3. Never append to files — write the complete content each time
143
+ 4. Use `ctx.force` to allow explicit re-creation when the user asks for it
144
+
145
+ ```typescript
146
+ export async function setupMyPlugin(ctx: PluginSetupContext): Promise<PluginSetupResult> {
147
+ const configPath = path.join(ctx.configDir, '.my-plugin.yaml');
148
+
149
+ // Idempotent: skip if already configured (unless --force)
150
+ if (fs.existsSync(configPath) && !ctx.force) {
151
+ // Optionally validate the existing config
152
+ return { status: 'configured', message: 'Already configured' };
153
+ }
154
+
155
+ // Prompt only when needed
156
+ const apiKey = await ctx.prompt.input({
157
+ key: 'api-key',
158
+ message: 'Enter your API key:',
159
+ });
160
+
161
+ // Write complete config (not append)
162
+ fs.writeFileSync(configPath, `apiKey: "${apiKey}"\n`);
163
+ return { status: 'configured', configCreated: ['config/.my-plugin.yaml'] };
164
+ }
165
+ ```
166
+
67
167
  ### PluginSetupContext
68
168
 
69
- | Field | Type | Description |
70
- | ------------- | --------- | ----------------------------------------------------------------- |
71
- | `pluginName` | `string` | Plugin name from plugin.yaml |
72
- | `projectRoot` | `string` | Absolute project root path |
73
- | `configDir` | `string` | Config directory (from `.jay` configBase, defaults to `./config`) |
74
- | `services` | `Map` | Registered services (may be empty if init failed) |
75
- | `initError` | `Error?` | Present if plugin init failed — check this before using services |
76
- | `force` | `boolean` | Whether `--force` flag was passed |
169
+ | Field | Type | Description |
170
+ | ------------- | ------------------- | ----------------------------------------------------------------- |
171
+ | `pluginName` | `string` | Plugin name from plugin.yaml |
172
+ | `projectRoot` | `string` | Absolute project root path |
173
+ | `configDir` | `string` | Config directory (from `.jay` configBase, defaults to `./config`) |
174
+ | `services` | `Map` | Registered services (may be empty if init failed) |
175
+ | `initError` | `Error?` | Present if plugin init failed — check this before using services |
176
+ | `force` | `boolean` | Whether `--force` flag was passed |
177
+ | `interactive` | `boolean` | Whether running in interactive mode (can prompt user) |
178
+ | `prompt` | `PluginSetupPrompt` | Prompt functions for user input (see below) |
179
+
180
+ ### PluginSetupPrompt
181
+
182
+ | Method | Signature | Description |
183
+ | --------- | -------------------------------------------------- | ---------------------------------------------------------- |
184
+ | `input` | `(opts: { message, validate? }) → Promise<string>` | Text input. Non-interactive: returns `""` |
185
+ | `confirm` | `(opts: { message, default? }) → Promise<boolean>` | Yes/no. Non-interactive: returns `default` or `false` |
186
+ | `select` | `(opts: { message, choices }) → Promise<string>` | Single choice. Non-interactive: returns first choice value |
77
187
 
78
188
  ### PluginSetupResult
79
189
 
package/dist/index.js CHANGED
@@ -10,7 +10,7 @@ import YAML from "yaml";
10
10
  import { getLogger, setDevLogger, createDevLogger } from "@jay-framework/logger";
11
11
  import { parseJayFile, JAY_IMPORT_RESOLVER, generateElementDefinitionFile, ContractTagType, parseContract, generateElementFile, generateServerElementFile, htmlElementTagNameMap, loadLinkedContract, getLinkedContractDir } from "@jay-framework/compiler-jay-html";
12
12
  import { JAY_CONTRACT_EXTENSION, JAY_EXTENSION, resolvePluginManifest, LOCAL_PLUGIN_PATH, JayAtomicType, JayEnumType, loadPluginManifest, RuntimeMode, GenerateTarget, findDynamicContract } from "@jay-framework/compiler-shared";
13
- import { scanPlugins as scanPlugins$1, listContracts, materializeContracts } from "@jay-framework/stack-server-runtime";
13
+ import { scanPlugins as scanPlugins$1, listContracts, materializeContracts, SetupNeedsAnswerError } from "@jay-framework/stack-server-runtime";
14
14
  import { listContracts as listContracts2, materializeContracts as materializeContracts2 } from "@jay-framework/stack-server-runtime";
15
15
  import { Command } from "commander";
16
16
  import chalk from "chalk";
@@ -20,6 +20,7 @@ import { createRequire } from "module";
20
20
  import { glob } from "glob";
21
21
  import fsSync from "node:fs";
22
22
  import { fileURLToPath } from "node:url";
23
+ import { input, confirm, select } from "@inquirer/prompts";
23
24
  const DEFAULT_CONFIG = {
24
25
  devServer: {
25
26
  portRange: [3e3, 3100],
@@ -5958,7 +5959,7 @@ async function runAction(actionRef, options, projectRoot, initializeServices) {
5958
5959
  process.exit(1);
5959
5960
  }
5960
5961
  const actionExport = actionRef.substring(slashIndex + 1);
5961
- const input = options.input ? JSON.parse(options.input) : {};
5962
+ const input2 = options.input ? JSON.parse(options.input) : {};
5962
5963
  if (options.verbose) {
5963
5964
  getLogger().info("Starting Vite for TypeScript support...");
5964
5965
  }
@@ -5991,9 +5992,9 @@ async function runAction(actionRef, options, projectRoot, initializeServices) {
5991
5992
  }
5992
5993
  if (options.verbose) {
5993
5994
  getLogger().info(`Executing action: ${matchedName}`);
5994
- getLogger().info(`Input: ${JSON.stringify(input)}`);
5995
+ getLogger().info(`Input: ${JSON.stringify(input2)}`);
5995
5996
  }
5996
- const result = await registry.execute(matchedName, input);
5997
+ const result = await registry.execute(matchedName, input2);
5997
5998
  if (result.success) {
5998
5999
  if (options.yaml) {
5999
6000
  getLogger().important(YAML.stringify(result.data));
@@ -6106,6 +6107,69 @@ async function runParams(contractRef, options, projectRoot, initializeServices)
6106
6107
  }
6107
6108
  }
6108
6109
  }
6110
+ function createInteractivePrompt() {
6111
+ return {
6112
+ async input(options) {
6113
+ return input({ message: options.message, validate: options.validate });
6114
+ },
6115
+ async confirm(options) {
6116
+ return confirm({ message: options.message, default: options.default });
6117
+ },
6118
+ async select(options) {
6119
+ return select({
6120
+ message: options.message,
6121
+ choices: options.choices.map((c) => ({ name: c.name, value: c.value }))
6122
+ });
6123
+ }
6124
+ };
6125
+ }
6126
+ function createAnswersFilePrompt(answers, pluginName) {
6127
+ return {
6128
+ async input(options) {
6129
+ const value = answers[options.key];
6130
+ if (value !== void 0)
6131
+ return value;
6132
+ throw new SetupNeedsAnswerError(pluginName, options.key, "input", options.message);
6133
+ },
6134
+ async confirm(options) {
6135
+ const value = answers[options.key];
6136
+ if (value !== void 0)
6137
+ return value === "true" || value === "yes";
6138
+ throw new SetupNeedsAnswerError(pluginName, options.key, "confirm", options.message);
6139
+ },
6140
+ async select(options) {
6141
+ const value = answers[options.key];
6142
+ if (value !== void 0)
6143
+ return value;
6144
+ throw new SetupNeedsAnswerError(
6145
+ pluginName,
6146
+ options.key,
6147
+ "select",
6148
+ options.message,
6149
+ options.choices
6150
+ );
6151
+ }
6152
+ };
6153
+ }
6154
+ function createDefaultPrompt(pluginName) {
6155
+ return {
6156
+ async input(options) {
6157
+ throw new SetupNeedsAnswerError(pluginName, options.key, "input", options.message);
6158
+ },
6159
+ async confirm(options) {
6160
+ throw new SetupNeedsAnswerError(pluginName, options.key, "confirm", options.message);
6161
+ },
6162
+ async select(options) {
6163
+ throw new SetupNeedsAnswerError(
6164
+ pluginName,
6165
+ options.key,
6166
+ "select",
6167
+ options.message,
6168
+ options.choices
6169
+ );
6170
+ }
6171
+ };
6172
+ }
6109
6173
  async function runSetup(pluginFilter, options, projectRoot, initializeServices) {
6110
6174
  let viteServer;
6111
6175
  try {
@@ -6145,6 +6209,11 @@ async function runSetup(pluginFilter, options, projectRoot, initializeServices)
6145
6209
  logger.info(chalk.yellow(`⚠️ ${name} init error: ${err.message}`));
6146
6210
  }
6147
6211
  }
6212
+ const interactive = options.interactive === true;
6213
+ let answersMap;
6214
+ if (options.answers) {
6215
+ answersMap = YAML.parse(fsSync.readFileSync(options.answers, "utf-8")) || {};
6216
+ }
6148
6217
  let configured = 0;
6149
6218
  let needsConfig = 0;
6150
6219
  let errors = 0;
@@ -6153,11 +6222,14 @@ async function runSetup(pluginFilter, options, projectRoot, initializeServices)
6153
6222
  if (plugin.setupDescription && options.verbose) {
6154
6223
  logger.important(chalk.gray(` ${plugin.setupDescription}`));
6155
6224
  }
6225
+ const prompt = interactive ? createInteractivePrompt() : answersMap ? createAnswersFilePrompt(answersMap, plugin.name) : createDefaultPrompt(plugin.name);
6156
6226
  try {
6157
6227
  const result = await executePluginSetup(plugin, {
6158
6228
  projectRoot,
6159
6229
  configDir,
6160
6230
  force: options.force ?? false,
6231
+ interactive,
6232
+ prompt,
6161
6233
  initError: initErrors.get(plugin.name),
6162
6234
  viteServer,
6163
6235
  verbose: options.verbose
@@ -6200,10 +6272,34 @@ async function runSetup(pluginFilter, options, projectRoot, initializeServices)
6200
6272
  break;
6201
6273
  }
6202
6274
  } catch (error) {
6203
- errors++;
6204
- logger.important(chalk.red(` ❌ Setup failed: ${error.message}`));
6205
- if (options.verbose) {
6206
- logger.error(error.stack);
6275
+ if (error instanceof SetupNeedsAnswerError) {
6276
+ needsConfig++;
6277
+ logger.important("");
6278
+ logger.important(chalk.yellow("setup-needs-answer:"));
6279
+ logger.important(chalk.yellow(` plugin: ${error.plugin}`));
6280
+ logger.important(chalk.yellow(` key: ${error.key}`));
6281
+ logger.important(chalk.yellow(` type: ${error.type}`));
6282
+ logger.important(chalk.yellow(` message: "${error.promptMessage}"`));
6283
+ if (error.choices) {
6284
+ logger.important(chalk.yellow(" choices:"));
6285
+ for (const c of error.choices) {
6286
+ logger.important(chalk.yellow(` - ${c.value}: ${c.name}`));
6287
+ }
6288
+ }
6289
+ logger.important("");
6290
+ logger.important(chalk.gray("Provide the answer via file:"));
6291
+ logger.important(chalk.gray(` jay-stack-cli setup --answers answers.yaml`));
6292
+ logger.important(chalk.gray(` answers.yaml format:`));
6293
+ logger.important(chalk.gray(` ${error.key}: "your-answer"`));
6294
+ logger.important("");
6295
+ logger.important(chalk.gray("Or run interactively:"));
6296
+ logger.important(chalk.gray(` jay-stack-cli setup --interactive`));
6297
+ } else {
6298
+ errors++;
6299
+ logger.important(chalk.red(` ❌ Setup failed: ${error.message}`));
6300
+ if (options.verbose) {
6301
+ logger.error(error.stack);
6302
+ }
6207
6303
  }
6208
6304
  }
6209
6305
  logger.important("");
@@ -6284,11 +6380,11 @@ async function runCommand(commandRef, rawArgs, options, projectRoot, initializeS
6284
6380
  }
6285
6381
  process.exit(1);
6286
6382
  }
6287
- let input = {};
6383
+ let input2 = {};
6288
6384
  if (command.metadata?.inputSchema) {
6289
6385
  const flagDefs = commandSchemaToFlags(command.metadata.inputSchema);
6290
6386
  const rawOptions = parseRawFlags(rawArgs, flagDefs);
6291
- input = parseInputFromFlags(rawOptions, command.metadata.inputSchema);
6387
+ input2 = parseInputFromFlags(rawOptions, command.metadata.inputSchema);
6292
6388
  }
6293
6389
  if (options.verbose) {
6294
6390
  getLogger().info("Starting Vite for TypeScript support...");
@@ -6319,7 +6415,7 @@ async function runCommand(commandRef, rawArgs, options, projectRoot, initializeS
6319
6415
  if (options.verbose) {
6320
6416
  getLogger().info(`Executing ${command.pluginName}/${command.commandName}...`);
6321
6417
  }
6322
- const result = await executePluginCommand(command, input, viteServer);
6418
+ const result = await executePluginCommand(command, input2, viteServer);
6323
6419
  if (!result.success) {
6324
6420
  process.exit(1);
6325
6421
  }
@@ -6459,7 +6555,7 @@ program.command("validate-plugin").description("Validate a Jay Stack plugin pack
6459
6555
  process.exit(1);
6460
6556
  }
6461
6557
  });
6462
- program.command("setup [plugin]").description("Run plugin setup: config templates, credential validation, reference data").option("--force", "Force re-run (overwrite config templates and regenerate references)").option("-v, --verbose", "Show detailed output").action(async (plugin, options) => {
6558
+ program.command("setup [plugin]").description("Run plugin setup: config templates, credential validation, reference data").option("--force", "Force re-run (overwrite config templates and regenerate references)").option("--interactive", "Prompt for input via terminal (for humans)").option("--answers <file>", "Read answers from YAML file (for agents)").option("-v, --verbose", "Show detailed output").action(async (plugin, options) => {
6463
6559
  await runSetup(plugin, options, process.cwd(), initializeServicesForCli);
6464
6560
  });
6465
6561
  program.command("agent-kit").description("Prepare agent kit: materialize contracts, generate references, write docs").option("-o, --output <dir>", "Output directory (default: agent-kit/materialized-contracts)").option("--yaml", "Output contract index as YAML to stdout").option("--list", "List contracts without writing files").option("--plugin <name>", "Filter to specific plugin").option("--dynamic-only", "Only process dynamic contracts").option("--force", "Force re-materialization").option("--no-references", "Skip reference data generation").option(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jay-framework/jay-stack-cli",
3
- "version": "0.22.0",
3
+ "version": "0.22.2",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -24,15 +24,16 @@
24
24
  "test:watch": "vitest"
25
25
  },
26
26
  "dependencies": {
27
- "@jay-framework/compiler-jay-html": "^0.22.0",
28
- "@jay-framework/compiler-shared": "^0.22.0",
29
- "@jay-framework/dev-server": "^0.22.0",
30
- "@jay-framework/editor-server": "^0.22.0",
31
- "@jay-framework/fullstack-component": "^0.22.0",
32
- "@jay-framework/logger": "^0.22.0",
33
- "@jay-framework/plugin-validator": "^0.22.0",
34
- "@jay-framework/production-server": "^0.22.0",
35
- "@jay-framework/stack-server-runtime": "^0.22.0",
27
+ "@inquirer/prompts": "^8.5.2",
28
+ "@jay-framework/compiler-jay-html": "^0.22.2",
29
+ "@jay-framework/compiler-shared": "^0.22.2",
30
+ "@jay-framework/dev-server": "^0.22.2",
31
+ "@jay-framework/editor-server": "^0.22.2",
32
+ "@jay-framework/fullstack-component": "^0.22.2",
33
+ "@jay-framework/logger": "^0.22.2",
34
+ "@jay-framework/plugin-validator": "^0.22.2",
35
+ "@jay-framework/production-server": "^0.22.2",
36
+ "@jay-framework/stack-server-runtime": "^0.22.2",
36
37
  "chalk": "^4.1.2",
37
38
  "commander": "^14.0.0",
38
39
  "express": "^5.0.1",
@@ -43,7 +44,7 @@
43
44
  "yaml": "^2.3.4"
44
45
  },
45
46
  "devDependencies": {
46
- "@jay-framework/dev-environment": "^0.22.0",
47
+ "@jay-framework/dev-environment": "^0.22.2",
47
48
  "@types/express": "^5.0.2",
48
49
  "@types/node": "^22.15.21",
49
50
  "nodemon": "^3.0.3",