@memberjunction/cli 6.1.3 → 6.2.0-edge.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.
Files changed (40) hide show
  1. package/README.md +18 -7
  2. package/dist/commands/agent/init.d.ts +23 -0
  3. package/dist/commands/agent/init.d.ts.map +1 -0
  4. package/dist/commands/agent/init.js +222 -0
  5. package/dist/commands/agent/init.js.map +1 -0
  6. package/dist/commands/doctor/index.d.ts +6 -4
  7. package/dist/commands/doctor/index.d.ts.map +1 -1
  8. package/dist/commands/doctor/index.js +43 -18
  9. package/dist/commands/doctor/index.js.map +1 -1
  10. package/dist/commands/test/scripts.d.ts +13 -0
  11. package/dist/commands/test/scripts.d.ts.map +1 -0
  12. package/dist/commands/test/scripts.js +50 -0
  13. package/dist/commands/test/scripts.js.map +1 -0
  14. package/dist/init-templates/citizen-builder/.agents/skills/new-agent/SKILL.md +66 -0
  15. package/dist/init-templates/citizen-builder/.agents/skills/package-agent/SKILL.md +69 -0
  16. package/dist/init-templates/citizen-builder/.agents/skills/test-agent/SKILL.md +61 -0
  17. package/dist/init-templates/citizen-builder/.claude/skills/new-agent/SKILL.md +66 -0
  18. package/dist/init-templates/citizen-builder/.claude/skills/package-agent/SKILL.md +69 -0
  19. package/dist/init-templates/citizen-builder/.claude/skills/test-agent/SKILL.md +61 -0
  20. package/dist/init-templates/citizen-builder/.env.example +30 -0
  21. package/dist/init-templates/citizen-builder/AGENTS.md +331 -0
  22. package/dist/init-templates/citizen-builder/README.md +259 -0
  23. package/dist/init-templates/citizen-builder/docker/Dockerfile +16 -0
  24. package/dist/init-templates/citizen-builder/docker-compose.yml +59 -0
  25. package/dist/init-templates/citizen-builder/docs/ENTERPRISE_ORG_SETUP.md +73 -0
  26. package/dist/init-templates/citizen-builder/docs/PROMOTION_GUIDE.md +70 -0
  27. package/dist/init-templates/citizen-builder/metadata/.mj-sync.json +7 -0
  28. package/dist/init-templates/citizen-builder/metadata/agents/.customer-insight-agent.json +55 -0
  29. package/dist/init-templates/citizen-builder/metadata/agents/.mj-sync.json +45 -0
  30. package/dist/init-templates/citizen-builder/metadata/prompts/.customer-insight-prompt.json +15 -0
  31. package/dist/init-templates/citizen-builder/metadata/prompts/.mj-sync.json +45 -0
  32. package/dist/init-templates/citizen-builder/metadata/prompts/templates/customer-insight.template.md +18 -0
  33. package/dist/init-templates/citizen-builder/scripts/bootstrap.sh +47 -0
  34. package/dist/init-templates/citizen-builder/scripts/docker-entrypoint.sh +184 -0
  35. package/dist/init-templates/citizen-builder/scripts/generate-capabilities.sh +74 -0
  36. package/dist/init-templates/citizen-builder/scripts/query-run-history.sh +34 -0
  37. package/dist/init-templates/citizen-builder/scripts/sync-metadata.sh +14 -0
  38. package/dist/init-templates/remote-mj/README.md +4 -4
  39. package/oclif.manifest.json +355 -197
  40. package/package.json +22 -22
package/README.md CHANGED
@@ -526,13 +526,24 @@ mj app check-updates
526
526
 
527
527
  #### Internal / dangerous flags
528
528
 
529
- Intentionally omitted from `--help`. Only for MJ-internal apps that own a
530
- reserved-looking schema (e.g. `__bcsaas`). Do not use on third-party apps.
531
-
532
- - `--dangerously-ignore-dbl-underscore-schema-rule` — available on `mj app install`
533
- and `mj app upgrade`. Bypasses the rule that blocks schema names starting with
534
- `__` (reserved for MJ internals). Exact-match reserved names (`__mj`, `dbo`,
535
- `sys`, `guest`, `INFORMATION_SCHEMA`) remain hard-blocked regardless.
529
+ Intentionally omitted from `--help`. Almost never needed: MJ's own Open Apps use the
530
+ `__mj_<AppName>` schema namespace (`__mj_BizAppsCommon`, `__mj_BizAppsForms`, …), which
531
+ installs on the default path with no flag at all.
532
+
533
+ - `--dangerously-ignore-dbl-underscore-schema-rule` — available on `mj app install`,
534
+ `mj app upgrade` and `mj app remove`. Allows a `__`-prefixed schema name *outside* the
535
+ `__mj_` app namespace (e.g. `__bcsaas`). Reserved schemas remain hard-blocked regardless,
536
+ on both supported platforms: every schema the **database** owns — `dbo`, `sys`, `guest`,
537
+ SQL Server's nine `db_*` fixed database-role schemas, `public`, anything starting `pg_`,
538
+ and `information_schema` — plus every schema **MJ** owns: `__mj` and `__mj_UDT`. Each of
539
+ these already exists in a stock database, so naming one would not create it, it would
540
+ *adopt* it — and `mj app remove` would then drop it.
541
+
542
+ Removing an app installed under one of those `__`-outside-namespace names (e.g. `__bcsaas`)
543
+ needs the same flag again: `mj app remove <app> --dangerously-ignore-dbl-underscore-schema-rule`
544
+ drops the schema. `--keep-data` is the exit for the platform- and MJ-reserved names above, which MJ
545
+ must never drop: `mj app remove <app> --keep-data` unregisters the app and leaves the
546
+ schema in place.
536
547
 
537
548
  ```bash
538
549
  mj app install https://github.com/BlueCypress/SaaS \
@@ -0,0 +1,23 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class AgentInit extends Command {
3
+ static description: string;
4
+ static aliases: string[];
5
+ static examples: string[];
6
+ static args: {
7
+ dir: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
8
+ };
9
+ static flags: {
10
+ force: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
11
+ start: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
12
+ app: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
13
+ 'skip-docker-check': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
14
+ };
15
+ run(): Promise<void>;
16
+ private resolveTemplateDir;
17
+ private ensureDockerRunning;
18
+ private startEnvironment;
19
+ private printDockerInstallInstructions;
20
+ private printNextSteps;
21
+ private printCodingAgentInstructions;
22
+ }
23
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/commands/agent/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,OAAO,EAAS,MAAM,aAAa,CAAC;AAUnD,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,OAAO;IAC5C,MAAM,CAAC,WAAW,SAC+G;IAEjI,MAAM,CAAC,OAAO,WAAsB;IAEpC,MAAM,CAAC,QAAQ,WAKb;IAEF,MAAM,CAAC,IAAI;;MAMT;IAEF,MAAM,CAAC,KAAK;;;;;MAmBV;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IA0E1B,OAAO,CAAC,kBAAkB;IAsB1B,OAAO,CAAC,mBAAmB;IAmC3B,OAAO,CAAC,gBAAgB;IAiCxB,OAAO,CAAC,8BAA8B;IActC,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,4BAA4B;CAcrC"}
@@ -0,0 +1,222 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { existsSync, mkdirSync, cpSync, copyFileSync, readFileSync, writeFileSync } from 'node:fs';
3
+ import path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { execSync } from 'node:child_process';
6
+ import chalk from 'chalk';
7
+ import ora from 'ora-classic';
8
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
9
+ export default class AgentInit extends Command {
10
+ static { this.description = 'Initialize a MemberJunction Citizen Agent Builder environment in the current or specified directory, including Docker setup.'; }
11
+ static { this.aliases = ['ai:agents:init']; }
12
+ static { this.examples = [
13
+ '<%= config.bin %> <%= command.id %>',
14
+ '<%= config.bin %> <%= command.id %> ./my-agent-workspace',
15
+ '<%= config.bin %> <%= command.id %> --no-start',
16
+ '<%= config.bin %> <%= command.id %> --app https://github.com/BlueCypress/bc-sampledata',
17
+ ]; }
18
+ static { this.args = {
19
+ dir: Args.string({
20
+ description: 'Target directory for the agent builder environment (default: current directory).',
21
+ required: false,
22
+ default: '.',
23
+ }),
24
+ }; }
25
+ static { this.flags = {
26
+ force: Flags.boolean({
27
+ char: 'f',
28
+ description: 'Overwrite existing files in target directory if they already exist.',
29
+ default: false,
30
+ }),
31
+ start: Flags.boolean({
32
+ char: 's',
33
+ description: 'Start Docker containers and run bootstrap immediately after initialization (pass --no-start to skip).',
34
+ default: true,
35
+ allowNo: true,
36
+ }),
37
+ app: Flags.string({
38
+ description: 'Open App Git URL to install for business context (default: More Cheese).',
39
+ }),
40
+ 'skip-docker-check': Flags.boolean({
41
+ description: 'Skip verifying whether Docker Desktop is currently running.',
42
+ default: false,
43
+ }),
44
+ }; }
45
+ async run() {
46
+ const { args, flags } = await this.parse(AgentInit);
47
+ const targetDir = path.resolve(process.cwd(), args.dir);
48
+ this.log(chalk.bold.cyan('\n🚀 MemberJunction Citizen Agent Builder\n'));
49
+ // 1. Resolve template directory
50
+ const templateDir = this.resolveTemplateDir();
51
+ if (!templateDir) {
52
+ this.error(chalk.red('✗ Citizen Agent Builder template assets could not be located.\n') +
53
+ 'Please ensure @memberjunction/cli is properly installed.');
54
+ }
55
+ // 2. Check Docker availability & attempt auto-launch if stopped on macOS
56
+ const dockerAvailable = flags['skip-docker-check'] ? false : this.ensureDockerRunning();
57
+ // 3. Ensure target directory exists
58
+ if (!existsSync(targetDir)) {
59
+ mkdirSync(targetDir, { recursive: true });
60
+ }
61
+ // 4. Check for existing files
62
+ const agentsMdPath = path.join(targetDir, 'AGENTS.md');
63
+ if (existsSync(agentsMdPath) && !flags.force) {
64
+ this.log(chalk.yellow(`Target directory '${targetDir}' already contains AGENTS.md.\nUse --force to overwrite existing files.\n`));
65
+ return;
66
+ }
67
+ // 5. Scaffold files
68
+ const spinner = ora('Scaffolding agent builder workspace...').start();
69
+ try {
70
+ cpSync(templateDir, targetDir, { recursive: true });
71
+ // Create .env from .env.example if missing
72
+ const envExamplePath = path.join(targetDir, '.env.example');
73
+ const envPath = path.join(targetDir, '.env');
74
+ if (existsSync(envExamplePath) && !existsSync(envPath)) {
75
+ copyFileSync(envExamplePath, envPath);
76
+ }
77
+ // If custom app URL was supplied, update .env
78
+ if (flags.app && existsSync(envPath)) {
79
+ let envContent = readFileSync(envPath, 'utf8');
80
+ envContent = envContent.replace(/OPEN_APP_INSTALL_URL=.*/, `OPEN_APP_INSTALL_URL=${flags.app}`);
81
+ writeFileSync(envPath, envContent, 'utf8');
82
+ }
83
+ spinner.succeed(chalk.green('Workspace scaffolded successfully!'));
84
+ }
85
+ catch (err) {
86
+ spinner.fail(chalk.red('Failed to scaffold workspace.'));
87
+ const errorMsg = err instanceof Error ? err.message : String(err);
88
+ this.error(errorMsg);
89
+ }
90
+ // 6. Start Docker and bootstrap if requested and available
91
+ if (flags.start && dockerAvailable) {
92
+ this.startEnvironment(targetDir);
93
+ }
94
+ else {
95
+ if (!dockerAvailable && !flags['skip-docker-check']) {
96
+ this.printDockerInstallInstructions();
97
+ }
98
+ this.printNextSteps(targetDir, dockerAvailable);
99
+ }
100
+ }
101
+ resolveTemplateDir() {
102
+ // 1. Check bundled template ({src,dist}/init-templates/citizen-builder)
103
+ const bundledPath = path.join(__dirname, '..', '..', 'init-templates', 'citizen-builder');
104
+ if (existsSync(bundledPath)) {
105
+ return bundledPath;
106
+ }
107
+ // 2. Check src template when running from dist in dev mode
108
+ const bundledSrcPath = path.join(__dirname, '..', '..', '..', 'src', 'init-templates', 'citizen-builder');
109
+ if (existsSync(bundledSrcPath)) {
110
+ return bundledSrcPath;
111
+ }
112
+ // 3. Check monorepo root fallback (5 levels up from commands/agent)
113
+ const monorepoRootPath = path.resolve(__dirname, '../../../../../citizen-builder');
114
+ if (existsSync(monorepoRootPath)) {
115
+ return monorepoRootPath;
116
+ }
117
+ return null;
118
+ }
119
+ ensureDockerRunning() {
120
+ // Step 1: Check if docker daemon is already responsive
121
+ try {
122
+ execSync('docker info', { stdio: 'ignore' });
123
+ return true;
124
+ }
125
+ catch {
126
+ // Daemon not answering
127
+ }
128
+ // Step 2: If macOS and Docker.app exists, try launching it automatically
129
+ if (process.platform === 'darwin' && existsSync('/Applications/Docker.app')) {
130
+ const launchSpinner = ora('Docker Desktop is installed but not running. Launching Docker Desktop...').start();
131
+ try {
132
+ execSync('open -a Docker', { stdio: 'ignore' });
133
+ // Poll for up to 20 seconds for the daemon socket
134
+ for (let i = 0; i < 20; i++) {
135
+ try {
136
+ execSync('docker info', { stdio: 'ignore' });
137
+ launchSpinner.succeed(chalk.green('Docker Desktop started!'));
138
+ return true;
139
+ }
140
+ catch {
141
+ execSync('sleep 1');
142
+ }
143
+ }
144
+ launchSpinner.warn(chalk.yellow('Docker Desktop is still initializing in the background.'));
145
+ return false;
146
+ }
147
+ catch {
148
+ launchSpinner.fail(chalk.yellow('Could not launch Docker Desktop automatically.'));
149
+ return false;
150
+ }
151
+ }
152
+ return false;
153
+ }
154
+ startEnvironment(targetDir) {
155
+ const spinner = ora('Starting MemberJunction container stack (docker compose up -d)...').start();
156
+ try {
157
+ execSync('docker compose up -d', { cwd: targetDir, stdio: 'pipe' });
158
+ spinner.succeed(chalk.green('Containers started!'));
159
+ }
160
+ catch (err) {
161
+ spinner.fail(chalk.red('Failed to start containers.'));
162
+ const errorMsg = err instanceof Error ? err.message : String(err);
163
+ this.error(errorMsg);
164
+ }
165
+ let apiPort = '4000';
166
+ let dbPort = '1433';
167
+ let explorerPort = '4202';
168
+ const envPath = path.join(targetDir, '.env');
169
+ if (existsSync(envPath)) {
170
+ const content = readFileSync(envPath, 'utf8');
171
+ const apiMatch = content.match(/^API_PORT=(\d+)/m);
172
+ if (apiMatch)
173
+ apiPort = apiMatch[1];
174
+ const dbMatch = content.match(/^DB_PORT=(\d+)/m);
175
+ if (dbMatch)
176
+ dbPort = dbMatch[1];
177
+ const explorerMatch = content.match(/^EXPLORER_PORT=(\d+)/m);
178
+ if (explorerMatch)
179
+ explorerPort = explorerMatch[1];
180
+ }
181
+ this.log(chalk.bold.cyan('\n🎉 Your MemberJunction local instance is running!'));
182
+ this.log(` API Endpoint: ${chalk.green(`http://localhost:${apiPort}`)}`);
183
+ this.log(` Explorer UI: ${chalk.green(`http://localhost:${explorerPort}`)}`);
184
+ this.log(` Database: ${chalk.green(`localhost:${dbPort}`)} (DB: MemberJunction)`);
185
+ this.log(` Healthcheck: ${chalk.gray(`http://localhost:${apiPort}/healthcheck`)}\n`);
186
+ this.printCodingAgentInstructions();
187
+ }
188
+ printDockerInstallInstructions() {
189
+ this.log(chalk.yellow('\n⚠️ Docker Desktop is not installed or not running.'));
190
+ this.log('MemberJunction Agent Builder requires Docker Desktop to run your local database and API.\n');
191
+ this.log(chalk.bold('To install Docker Desktop:'));
192
+ if (process.platform === 'darwin') {
193
+ this.log(' • Download: ' + chalk.cyan('https://www.docker.com/products/docker-desktop'));
194
+ this.log(' • Or install via Homebrew: ' + chalk.cyan('brew install --cask docker'));
195
+ }
196
+ else if (process.platform === 'win32') {
197
+ this.log(' • Download: ' + chalk.cyan('https://www.docker.com/products/docker-desktop'));
198
+ }
199
+ else {
200
+ this.log(' • Install Docker Engine: ' + chalk.cyan('https://docs.docker.com/engine/install/'));
201
+ }
202
+ }
203
+ printNextSteps(targetDir, dockerAvailable) {
204
+ this.log(chalk.bold.white('\n📋 Next Steps:'));
205
+ this.log(`1. Navigate to your workspace:\n ${chalk.cyan(`cd ${path.relative(process.cwd(), targetDir) || '.'}`)}`);
206
+ this.log(`2. Add your LLM API keys in ${chalk.yellow('.env')}`);
207
+ if (dockerAvailable) {
208
+ this.log(`3. Start your local environment:\n ${chalk.cyan('docker compose up -d')}`);
209
+ }
210
+ else {
211
+ this.log(`3. Launch Docker Desktop and run:\n ${chalk.cyan('docker compose up -d')}`);
212
+ }
213
+ this.printCodingAgentInstructions();
214
+ }
215
+ printCodingAgentInstructions() {
216
+ this.log(chalk.bold.green('\n🤖 Ready to Build with your Coding Agent:'));
217
+ this.log('Open your coding agent (Claude Code, Antigravity, Cursor, etc.) in this folder and simply say:');
218
+ this.log(chalk.italic.white(' "Build me an agent that scans for overdue invoices and prepares reminder emails."'));
219
+ this.log(chalk.gray('Your coding agent will read AGENTS.md, author the declarative metadata, and test it against your local database!\n'));
220
+ }
221
+ }
222
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/commands/agent/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACnG,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,aAAa,CAAC;AAE9B,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE/D,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,OAAO;aACrC,gBAAW,GAChB,8HAA8H,CAAC;aAE1H,YAAO,GAAG,CAAC,gBAAgB,CAAC,CAAC;aAE7B,aAAQ,GAAG;QAChB,qCAAqC;QACrC,0DAA0D;QAC1D,gDAAgD;QAChD,wFAAwF;KACzF,CAAC;aAEK,SAAI,GAAG;QACZ,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC;YACf,WAAW,EAAE,kFAAkF;YAC/F,QAAQ,EAAE,KAAK;YACf,OAAO,EAAE,GAAG;SACb,CAAC;KACH,CAAC;aAEK,UAAK,GAAG;QACb,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC;YACnB,IAAI,EAAE,GAAG;YACT,WAAW,EAAE,qEAAqE;YAClF,OAAO,EAAE,KAAK;SACf,CAAC;QACF,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC;YACnB,IAAI,EAAE,GAAG;YACT,WAAW,EAAE,uGAAuG;YACpH,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,IAAI;SACd,CAAC;QACF,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC;YAChB,WAAW,EAAE,0EAA0E;SACxF,CAAC;QACF,mBAAmB,EAAE,KAAK,CAAC,OAAO,CAAC;YACjC,WAAW,EAAE,6DAA6D;YAC1E,OAAO,EAAE,KAAK;SACf,CAAC;KACH,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACpD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QAExD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC,CAAC;QAEzE,gCAAgC;QAChC,MAAM,WAAW,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC9C,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,IAAI,CAAC,KAAK,CACR,KAAK,CAAC,GAAG,CAAC,iEAAiE,CAAC;gBAC1E,0DAA0D,CAC7D,CAAC;QACJ,CAAC;QAED,yEAAyE;QACzE,MAAM,eAAe,GAAG,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAExF,oCAAoC;QACpC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3B,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5C,CAAC;QAED,8BAA8B;QAC9B,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QACvD,IAAI,UAAU,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YAC7C,IAAI,CAAC,GAAG,CACN,KAAK,CAAC,MAAM,CACV,qBAAqB,SAAS,2EAA2E,CAC1G,CACF,CAAC;YACF,OAAO;QACT,CAAC;QAED,oBAAoB;QACpB,MAAM,OAAO,GAAG,GAAG,CAAC,wCAAwC,CAAC,CAAC,KAAK,EAAE,CAAC;QACtE,IAAI,CAAC;YACH,MAAM,CAAC,WAAW,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAEpD,2CAA2C;YAC3C,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;YAC5D,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;YAC7C,IAAI,UAAU,CAAC,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBACvD,YAAY,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;YACxC,CAAC;YAED,8CAA8C;YAC9C,IAAI,KAAK,CAAC,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBACrC,IAAI,UAAU,GAAG,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;gBAC/C,UAAU,GAAG,UAAU,CAAC,OAAO,CAC7B,yBAAyB,EACzB,wBAAwB,KAAK,CAAC,GAAG,EAAE,CACpC,CAAC;gBACF,aAAa,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;YAC7C,CAAC;YAED,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC,CAAC;QACrE,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC,CAAC;YACzD,MAAM,QAAQ,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAClE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACvB,CAAC;QAED,2DAA2D;QAC3D,IAAI,KAAK,CAAC,KAAK,IAAI,eAAe,EAAE,CAAC;YACnC,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;QACnC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,eAAe,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,EAAE,CAAC;gBACpD,IAAI,CAAC,8BAA8B,EAAE,CAAC;YACxC,CAAC;YACD,IAAI,CAAC,cAAc,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAEO,kBAAkB;QACxB,wEAAwE;QACxE,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,gBAAgB,EAAE,iBAAiB,CAAC,CAAC;QAC1F,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC5B,OAAO,WAAW,CAAC;QACrB,CAAC;QAED,2DAA2D;QAC3D,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,CAAC,CAAC;QAC1G,IAAI,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;YAC/B,OAAO,cAAc,CAAC;QACxB,CAAC;QAED,oEAAoE;QACpE,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,gCAAgC,CAAC,CAAC;QACnF,IAAI,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;YACjC,OAAO,gBAAgB,CAAC;QAC1B,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,mBAAmB;QACzB,uDAAuD;QACvD,IAAI,CAAC;YACH,QAAQ,CAAC,aAAa,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;YAC7C,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,uBAAuB;QACzB,CAAC;QAED,yEAAyE;QACzE,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,IAAI,UAAU,CAAC,0BAA0B,CAAC,EAAE,CAAC;YAC5E,MAAM,aAAa,GAAG,GAAG,CAAC,0EAA0E,CAAC,CAAC,KAAK,EAAE,CAAC;YAC9G,IAAI,CAAC;gBACH,QAAQ,CAAC,gBAAgB,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;gBAChD,kDAAkD;gBAClD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC5B,IAAI,CAAC;wBACH,QAAQ,CAAC,aAAa,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;wBAC7C,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;wBAC9D,OAAO,IAAI,CAAC;oBACd,CAAC;oBAAC,MAAM,CAAC;wBACP,QAAQ,CAAC,SAAS,CAAC,CAAC;oBACtB,CAAC;gBACH,CAAC;gBACD,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,yDAAyD,CAAC,CAAC,CAAC;gBAC5F,OAAO,KAAK,CAAC;YACf,CAAC;YAAC,MAAM,CAAC;gBACP,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,gDAAgD,CAAC,CAAC,CAAC;gBACnF,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,gBAAgB,CAAC,SAAiB;QACxC,MAAM,OAAO,GAAG,GAAG,CAAC,mEAAmE,CAAC,CAAC,KAAK,EAAE,CAAC;QACjG,IAAI,CAAC;YACH,QAAQ,CAAC,sBAAsB,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;YACpE,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC;QACtD,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC,CAAC;YACvD,MAAM,QAAQ,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAClE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACvB,CAAC;QAED,IAAI,OAAO,GAAG,MAAM,CAAC;QACrB,IAAI,MAAM,GAAG,MAAM,CAAC;QACpB,IAAI,YAAY,GAAG,MAAM,CAAC;QAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAC7C,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACxB,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC9C,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;YACnD,IAAI,QAAQ;gBAAE,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;YACpC,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;YACjD,IAAI,OAAO;gBAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YACjC,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;YAC7D,IAAI,aAAa;gBAAE,YAAY,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;QACrD,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,qDAAqD,CAAC,CAAC,CAAC;QACjF,IAAI,CAAC,GAAG,CAAC,uBAAuB,KAAK,CAAC,KAAK,CAAC,oBAAoB,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;QAC9E,IAAI,CAAC,GAAG,CAAC,uBAAuB,KAAK,CAAC,KAAK,CAAC,oBAAoB,YAAY,EAAE,CAAC,EAAE,CAAC,CAAC;QACnF,IAAI,CAAC,GAAG,CAAC,uBAAuB,KAAK,CAAC,KAAK,CAAC,aAAa,MAAM,EAAE,CAAC,uBAAuB,CAAC,CAAC;QAC3F,IAAI,CAAC,GAAG,CAAC,uBAAuB,KAAK,CAAC,IAAI,CAAC,oBAAoB,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;QAC3F,IAAI,CAAC,4BAA4B,EAAE,CAAC;IACtC,CAAC;IAEO,8BAA8B;QACpC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,uDAAuD,CAAC,CAAC,CAAC;QAChF,IAAI,CAAC,GAAG,CAAC,4FAA4F,CAAC,CAAC;QACvG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC,CAAC;QACnD,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAClC,IAAI,CAAC,GAAG,CAAC,gBAAgB,GAAG,KAAK,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC,CAAC;YAC1F,IAAI,CAAC,GAAG,CAAC,+BAA+B,GAAG,KAAK,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC,CAAC;QACvF,CAAC;aAAM,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;YACxC,IAAI,CAAC,GAAG,CAAC,gBAAgB,GAAG,KAAK,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC,CAAC;QAC5F,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,GAAG,CAAC,6BAA6B,GAAG,KAAK,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC,CAAC;QAClG,CAAC;IACH,CAAC;IAEO,cAAc,CAAC,SAAiB,EAAE,eAAwB;QAChE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC;QAC/C,IAAI,CAAC,GAAG,CAAC,sCAAsC,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,IAAI,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QACrH,IAAI,CAAC,GAAG,CAAC,+BAA+B,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAChE,IAAI,eAAe,EAAE,CAAC;YACpB,IAAI,CAAC,GAAG,CAAC,wCAAwC,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAC;QACzF,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,GAAG,CAAC,yCAAyC,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAC;QAC1F,CAAC;QACD,IAAI,CAAC,4BAA4B,EAAE,CAAC;IACtC,CAAC;IAEO,4BAA4B;QAClC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC,CAAC;QAC1E,IAAI,CAAC,GAAG,CAAC,gGAAgG,CAAC,CAAC;QAC3G,IAAI,CAAC,GAAG,CACN,KAAK,CAAC,MAAM,CAAC,KAAK,CAChB,qFAAqF,CACtF,CACF,CAAC;QACF,IAAI,CAAC,GAAG,CACN,KAAK,CAAC,IAAI,CACR,oHAAoH,CACrH,CACF,CAAC;IACJ,CAAC"}
@@ -3,10 +3,12 @@ export default class Doctor extends Command {
3
3
  static description: string;
4
4
  static examples: string[];
5
5
  static flags: {
6
- dir: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
7
- verbose: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
8
- report: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
9
- report_extended: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
6
+ dir: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
7
+ scope: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
8
+ format: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
9
+ verbose: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
10
+ report: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
11
+ report_extended: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
10
12
  };
11
13
  run(): Promise<void>;
12
14
  private formatStatusIcon;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/doctor/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAC;AAU7C,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,OAAO;IACzC,MAAM,CAAC,WAAW,SAA4C;IAE9D,MAAM,CAAC,QAAQ,WAMb;IAEF,MAAM,CAAC,KAAK;;;;;MAgBV;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAqE1B,OAAO,CAAC,gBAAgB;CASzB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/doctor/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAC;AAY7C,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,OAAO;IACzC,MAAM,CAAC,WAAW,SAA4C;IAE9D,MAAM,CAAC,QAAQ,WAQb;IAEF,MAAM,CAAC,KAAK;;;;;;;MAqBV;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAuF1B,OAAO,CAAC,gBAAgB;CASzB"}
@@ -2,11 +2,15 @@ import { Command, Flags } from '@oclif/core';
2
2
  import chalk from 'chalk';
3
3
  import path from 'node:path';
4
4
  import { InstallerEngine, } from '@memberjunction/installer';
5
+ import { ResolveOutputFormat } from '@memberjunction/cli-core';
6
+ import { CANONICAL_FORMAT_FLAG } from '../../lib/format-compat.js';
5
7
  export default class Doctor extends Command {
6
8
  static { this.description = 'Diagnose a MemberJunction installation'; }
7
9
  static { this.examples = [
8
10
  '<%= config.bin %> <%= command.id %>',
9
11
  '<%= config.bin %> <%= command.id %> --dir ./my-mj-project',
12
+ '<%= config.bin %> <%= command.id %> --format json',
13
+ '<%= config.bin %> <%= command.id %> --scope ai',
10
14
  '<%= config.bin %> <%= command.id %> --verbose',
11
15
  '<%= config.bin %> <%= command.id %> --report',
12
16
  '<%= config.bin %> <%= command.id %> --report_extended',
@@ -16,6 +20,11 @@ export default class Doctor extends Command {
16
20
  description: 'Target directory to diagnose',
17
21
  default: '.',
18
22
  }),
23
+ scope: Flags.string({
24
+ description: 'Diagnostic scope to filter by (install, runtime, ai, metadata, agent)',
25
+ options: ['install', 'runtime', 'ai', 'metadata', 'agent'],
26
+ }),
27
+ format: CANONICAL_FORMAT_FLAG,
19
28
  verbose: Flags.boolean({
20
29
  char: 'v',
21
30
  description: 'Show detailed output including suggested fixes inline',
@@ -32,29 +41,42 @@ export default class Doctor extends Command {
32
41
  const { flags } = await this.parse(Doctor);
33
42
  const engine = new InstallerEngine();
34
43
  const targetDir = path.resolve(flags.dir);
35
- this.log('');
36
- this.log(chalk.bold('MJ Doctor'));
37
- this.log('─────────');
38
- engine.On('diagnostic', (event) => {
39
- const icon = this.formatStatusIcon(event.Status);
40
- this.log(`${icon} ${event.Message}`);
41
- if (event.SuggestedFix && flags.verbose) {
42
- this.log(chalk.dim(` Fix: ${event.SuggestedFix}`));
43
- }
44
- });
45
- // Capture log events for report path notification
46
- engine.On('log', (event) => {
47
- if (event.Message.startsWith('Diagnostic report saved to:')) {
48
- this.log('');
49
- this.log(chalk.cyan(event.Message));
50
- this.log(chalk.dim('Share this file when requesting installation support. Passwords are redacted.'));
51
- }
52
- });
44
+ const { format } = ResolveOutputFormat({ formatFlag: flags.format });
45
+ const isJson = format === 'json';
46
+ if (!isJson) {
47
+ this.log('');
48
+ this.log(chalk.bold('MJ Doctor'));
49
+ this.log('─────────');
50
+ engine.On('diagnostic', (event) => {
51
+ const icon = this.formatStatusIcon(event.Status);
52
+ this.log(`${icon} ${event.Message}`);
53
+ if (event.SuggestedFix && flags.verbose) {
54
+ this.log(chalk.dim(` Fix: ${event.SuggestedFix}`));
55
+ }
56
+ });
57
+ // Capture log events for report path notification
58
+ engine.On('log', (event) => {
59
+ if (event.Message.startsWith('Diagnostic report saved to:')) {
60
+ this.log('');
61
+ this.log(chalk.cyan(event.Message));
62
+ this.log(chalk.dim('Share this file when requesting installation support. Passwords are redacted.'));
63
+ }
64
+ });
65
+ }
53
66
  const result = await engine.Doctor(targetDir, {
54
67
  Verbose: flags.verbose,
55
68
  Report: flags.report,
56
69
  ReportExtended: flags.report_extended,
70
+ Scope: flags.scope,
71
+ Format: format,
57
72
  });
73
+ if (isJson) {
74
+ this.log(JSON.stringify(result.toJSON(), null, 2));
75
+ if (result.HasFailures) {
76
+ this.exit(1);
77
+ }
78
+ return;
79
+ }
58
80
  this.log('');
59
81
  if (result.HasFailures) {
60
82
  this.log(chalk.red.bold('Issues found:'));
@@ -88,6 +110,9 @@ export default class Doctor extends Command {
88
110
  this.log(chalk.dim('Extended report includes config file snapshots and service startup logs.'));
89
111
  }
90
112
  }
113
+ if (result.HasFailures) {
114
+ this.exit(1);
115
+ }
91
116
  }
92
117
  formatStatusIcon(status) {
93
118
  switch (status) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/doctor/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/doctor/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class TestScripts extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ test: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
7
+ promote: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
8
+ discard: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
9
+ yes: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
10
+ };
11
+ run(): Promise<void>;
12
+ }
13
+ //# sourceMappingURL=scripts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scripts.d.ts","sourceRoot":"","sources":["../../../src/commands/test/scripts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAC;AAE7C,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,OAAO;IAC9C,MAAM,CAAC,WAAW,SAGkE;IAEpF,MAAM,CAAC,QAAQ,WAMb;IAEF,MAAM,CAAC,KAAK;;;;;MAmBV;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAgB3B"}
@@ -0,0 +1,50 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ export default class TestScripts extends Command {
3
+ static { this.description = 'Review and promote recorded replay scripts. A run that re-derives a test which already had a ' +
4
+ 'script stores the new one as pending rather than replacing what replay uses, so a UI change ' +
5
+ 'never rewrites the suite unnoticed. This is where you see the drift and decide.'; }
6
+ static { this.examples = [
7
+ '<%= config.bin %> <%= command.id %>',
8
+ '<%= config.bin %> <%= command.id %> --test "T042 - Filter Grid"',
9
+ '<%= config.bin %> <%= command.id %> --promote --test "T042 - Filter Grid"',
10
+ '<%= config.bin %> <%= command.id %> --promote --yes',
11
+ '<%= config.bin %> <%= command.id %> --discard --test "T042 - Filter Grid"',
12
+ ]; }
13
+ static { this.flags = {
14
+ test: Flags.string({
15
+ description: 'Limit to one test, by name or ID',
16
+ }),
17
+ promote: Flags.boolean({
18
+ description: 'Promote the pending script(s) into the slot replay uses',
19
+ default: false,
20
+ exclusive: ['discard'],
21
+ }),
22
+ discard: Flags.boolean({
23
+ description: 'Drop the pending script(s), keeping the promoted one',
24
+ default: false,
25
+ exclusive: ['promote'],
26
+ }),
27
+ yes: Flags.boolean({
28
+ char: 'y',
29
+ description: 'Confirm a bulk --promote/--discard that was not narrowed with --test',
30
+ default: false,
31
+ }),
32
+ }; }
33
+ async run() {
34
+ const { flags } = await this.parse(TestScripts);
35
+ const { ScriptsCommand } = await import('@memberjunction/testing-cli');
36
+ try {
37
+ const scriptsCommand = new ScriptsCommand();
38
+ await scriptsCommand.execute({
39
+ test: flags.test,
40
+ promote: flags.promote,
41
+ discard: flags.discard,
42
+ yes: flags.yes,
43
+ });
44
+ }
45
+ catch (error) {
46
+ this.error(error);
47
+ }
48
+ }
49
+ }
50
+ //# sourceMappingURL=scripts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scripts.js","sourceRoot":"","sources":["../../../src/commands/test/scripts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,OAAO;aACvC,gBAAW,GAChB,+FAA+F;QAC/F,8FAA8F;QAC9F,iFAAiF,CAAC;aAE7E,aAAQ,GAAG;QAChB,qCAAqC;QACrC,iEAAiE;QACjE,2EAA2E;QAC3E,qDAAqD;QACrD,2EAA2E;KAC5E,CAAC;aAEK,UAAK,GAAG;QACb,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC;YACjB,WAAW,EAAE,kCAAkC;SAChD,CAAC;QACF,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC;YACrB,WAAW,EAAE,yDAAyD;YACtE,OAAO,EAAE,KAAK;YACd,SAAS,EAAE,CAAC,SAAS,CAAC;SACvB,CAAC;QACF,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC;YACrB,WAAW,EAAE,sDAAsD;YACnE,OAAO,EAAE,KAAK;YACd,SAAS,EAAE,CAAC,SAAS,CAAC;SACvB,CAAC;QACF,GAAG,EAAE,KAAK,CAAC,OAAO,CAAC;YACjB,IAAI,EAAE,GAAG;YACT,WAAW,EAAE,sEAAsE;YACnF,OAAO,EAAE,KAAK;SACf,CAAC;KACH,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAChD,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,6BAA6B,CAAC,CAAC;QAEvE,IAAI,CAAC;YACH,MAAM,cAAc,GAAG,IAAI,cAAc,EAAE,CAAC;YAC5C,MAAM,cAAc,CAAC,OAAO,CAAC;gBAC3B,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,GAAG,EAAE,KAAK,CAAC,GAAG;aACf,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,CAAC,KAAc,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC"}
@@ -0,0 +1,66 @@
1
+ ---
2
+ name: new-agent
3
+ description: Guides the coding agent to author a new MemberJunction agent and prompt metadata from user business intent.
4
+ ---
5
+
6
+ # Skill: `new-agent` (Authoring Declarative Agents)
7
+
8
+ Use this skill whenever the user asks to build, create, or modify a MemberJunction AI Agent.
9
+
10
+ ## Step 1: Elicit & Scope Business Intent
11
+ Ask clarifying questions if the requirement is ambiguous:
12
+ 1. **Goal**: What specific business problem does the agent solve?
13
+ 2. **Inputs & Subjects**: What input does the user provide (e.g. an account ID, order number, or topic)?
14
+ 3. **Data Sources**: Which entities does it read or check? (Cross-reference against `CAPABILITIES.md`).
15
+ 4. **Output / Action**: Does it produce an answer, a formatted summary, a notification, or trigger a downstream action?
16
+
17
+ ## Step 2: Determine Tier & Agent Type
18
+ - **Tier 1 (Preferred)**:
19
+ - If the agent follows a predictable sequence of steps, use **`TypeID: "@lookup:MJ: AI Agent Types.Name=Flow"`**.
20
+ - If the agent needs dynamic problem solving or open-ended tool calling, use **`TypeID: "@lookup:MJ: AI Agent Types.Name=Loop"`**.
21
+ - Always keep **`ModelSelectionMode: "Agent Type"`** and **`ExposeAsAction: false`**.
22
+ - **Tier 2 (Only if custom code is strictly necessary)**:
23
+ - If custom JavaScript formatting or computation is required that no existing action supports, create a sandboxed Runtime Action.
24
+ - Define an explicit `allowedEntities` list (never wildcards).
25
+
26
+ ## Step 3: Author Prompt Template & Metadata
27
+ 1. **Markdown Prompt Template**:
28
+ Save to: `metadata/prompts/templates/<agent-slug>.template.md`
29
+ Structure:
30
+ - Clear persona and objective.
31
+ - Exact instructions and step sequence.
32
+ - Business rules and edge-case handling.
33
+ - Explicit Markdown output formatting guidelines.
34
+
35
+ 2. **Prompt Metadata JSON**:
36
+ Save to: `metadata/prompts/.<agent-slug>-prompt.json`
37
+ ```json
38
+ [
39
+ {
40
+ "fields": {
41
+ "Name": "<Agent Name> Prompt",
42
+ "Description": "...",
43
+ "CategoryID": "@lookup:MJ: AI Prompt Categories.Name=Agent Type System Prompts",
44
+ "TypeID": "@lookup:MJ: AI Prompt Types.Name=Chat",
45
+ "Status": "Active",
46
+ "TemplateText": "@file:templates/<agent-slug>.template.md"
47
+ },
48
+ "primaryKey": { "ID": "<GENERATE-UUID-UPPERCASE>" }
49
+ }
50
+ ]
51
+ ```
52
+
53
+ 3. **Agent Metadata JSON**:
54
+ Save to: `metadata/agents/.<agent-slug>-agent.json`
55
+ Wire `MJ: AI Agent Prompts`, `MJ: AI Agent Steps`, and optional `MJ: AI Agent Actions`.
56
+
57
+ ## Step 4: Sync to Database
58
+ Run:
59
+ ```bash
60
+ ./scripts/sync-metadata.sh
61
+ ```
62
+ Verify that the sync command outputs success.
63
+
64
+ ## Step 5: Hand off to Testing
65
+ Inform the user that the agent has been created and synced:
66
+ *"I've created your agent '**<Agent Name>**' and synced it to your local environment. You can test it now in Explorer or ask me to run a test execution."*