@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
@@ -0,0 +1,73 @@
1
+ # Enterprise Organization Setup: Real Schemas & Business Context
2
+
3
+ This document explains how enterprise organizations—such as **Blue Cypress (BC)**—configure the MemberJunction Citizen Agent Builder so business users build agents against their **real entity schemas and business relationships** instead of generic defaults.
4
+
5
+ ---
6
+
7
+ ## 1. The Two-App Architecture
8
+
9
+ To provide an accurate, realistic authoring environment without exposing production customer data to personal machines, organizations publish two Open Apps:
10
+
11
+ | Application | Description | Carries |
12
+ |---|---|---|
13
+ | **`<org>-platform`** (e.g. `bc-platform`) | Core schema & business logic | Custom entities, fields, relationships, standard actions, and queries. |
14
+ | **`<org>-sampledata`** (e.g. `bc-sampledata`) | Realistic synthetic data | Loom-generated synthetic records mirroring production shapes and relational integrity. Depends on `<org>-platform`. |
15
+
16
+ When a citizen builder boots their environment and installs `<org>-sampledata`, MemberJunction's Open App dependency engine automatically resolves and installs `<org>-platform` leaf-first.
17
+
18
+ ### Why This Model Works:
19
+ 1. **Identical Entity Shapes:** Entity and field names match production exactly. An agent written against `bc-sampledata` works on production without renaming a single field or query.
20
+ 2. **Zero PII Risk:** The data is 100% synthetic by construction. Compliance and security reviews pass automatically.
21
+ 3. **Seamless Promotion:** Promotion is simply deploying the agent's metadata to the production instance; no code rewrites or schema remapping are needed.
22
+
23
+ ---
24
+
25
+ ## 2. Configuration for Citizen Builders
26
+
27
+ ### Option A: Private GitHub Repository Access (Recommended)
28
+ If your organization hosts `<org>-sampledata` in a private GitHub organization (e.g. `github.com/BlueCypress/`):
29
+
30
+ 1. Provide the user with a fine-grained, read-only GitHub Personal Access Token (PAT) with `Contents: Read` permission on the sample data and platform repositories.
31
+ 2. In the user's `.env`:
32
+ ```bash
33
+ # Enterprise Open App Target
34
+ OPEN_APP_INSTALL_URL=https://github.com/BlueCypress/bc-sampledata
35
+
36
+ # Read-only GitHub PAT for private repo authentication
37
+ GITHUB_TOKEN=ghp_exampleTokenWithReadOnlyAccess
38
+ ```
39
+ 3. Run the bootstrap script:
40
+ ```bash
41
+ docker compose exec api /work/scripts/bootstrap.sh
42
+ ```
43
+
44
+ ### Option B: Local Directory Mount (Zero Token)
45
+ If the user or team already has a local checkout of the platform app on their machine:
46
+ 1. Create a `docker-compose.override.yml`:
47
+ ```yaml
48
+ services:
49
+ api:
50
+ volumes:
51
+ - /path/to/local/bc-platform:/work/apps/bc-platform:ro
52
+ ```
53
+ 2. Run `mj app install /work/apps/bc-platform` inside the container.
54
+
55
+ ---
56
+
57
+ ## 3. Automated Capabilities Cataloging
58
+
59
+ Once your organization's Open App is installed, run:
60
+ ```bash
61
+ ./scripts/generate-capabilities.sh
62
+ ```
63
+ This queries your local database's entity and action catalogs to update `CAPABILITIES.md`. Your coding agent immediately learns every custom entity, field, and action specific to your company (e.g. `BC: Association Members`, `BC: Committee Terms`, `BC: Invoices`).
64
+
65
+ ---
66
+
67
+ ## 4. Packaging and Upstream Release of Sample Data
68
+
69
+ When updating your organization's synthetic dataset:
70
+ 1. Generate synthetic records using Loom.
71
+ 2. Push them to a staging database using `mj sync push`.
72
+ 3. Capture the differential SQL emitted by `packages/MetadataSync/src/lib/sql-logger.ts` as the next `V<timestamp>__v<version>_Metadata_Sync.sql` migration in `<org>-sampledata`.
73
+ 4. Publish a release of `<org>-sampledata`. All citizen builders will receive the updated synthetic records on their next bootstrap.
@@ -0,0 +1,70 @@
1
+ # Promotion & Governance Guide: Reviewing Packaged Agents
2
+
3
+ This guide is for MemberJunction platform administrators, team leads, and review boards responsible for evaluating and deploying agents authored via the Citizen Agent Builder.
4
+
5
+ ---
6
+
7
+ ## 1. What Arrives at Promotion
8
+
9
+ A citizen builder submits an export archive (e.g. `dist/InvoiceAuditAgent-package.zip`), which contains:
10
+
11
+ 1. **`AGENT_MANIFEST.md`**: An executive summary describing:
12
+ - What the agent does and who built it.
13
+ - Classification: **Tier 1 (Declarative)** vs **Tier 2 (Runtime Action)**.
14
+ - Data Footprint: Explicit list of entities read and entities modified.
15
+ - Sample Execution Receipt: Verification trace from a test run.
16
+ 2. **Metadata Files**:
17
+ - `metadata/agents/.*<name>*.json`
18
+ - `metadata/prompts/.*<name>*.json`
19
+ - `metadata/prompts/templates/<name>*.md`
20
+ - (If Tier 2) `metadata/actions/.*<name>*.json`
21
+
22
+ ---
23
+
24
+ ## 2. The Review Process
25
+
26
+ ### Tier 1 (Declarative Agents) — Fast Track (5-Minute Review)
27
+ Tier 1 agents contain **zero executable code** and **zero schema changes**. Reviewing them is straightforward:
28
+
29
+ 1. **Check Defaults in Manifest**:
30
+ - `ModelSelectionMode` is `"Agent Type"` (no hardcoded models).
31
+ - `ExposeAsAction` is `false` (unless a valid business rationale is documented).
32
+ 2. **Scan Prompts**:
33
+ - Verify no credentials, tokens, or raw SQL queries are embedded in prompt templates.
34
+ - Verify no hardcoded record IDs or personal names are used.
35
+ 3. **Approve**:
36
+ - Tier 1 submissions that satisfy these checks can be approved and imported immediately.
37
+
38
+ ### Tier 2 (Runtime Actions) — Code Review Gate
39
+ Tier 2 agents include custom JavaScript actions running in the MemberJunction sandboxed runtime:
40
+
41
+ 1. **Review JavaScript Logic**:
42
+ - Inspect the code inside the action's metadata definition.
43
+ - Ensure the logic is deterministic, handles errors, and contains no obfuscated operations or network calls.
44
+ 2. **Review & Narrow Permissions**:
45
+ - Verify that `allowedEntities` is an explicit, minimal list of required entities.
46
+ - **Reject any submission with `allowAnyEntity: true` or wildcard entity grants.**
47
+ 3. **Decide Graduation**:
48
+ - **Keep as Runtime Action**: Approve the action metadata for deployment as sandboxed JS.
49
+ - **Promote to Package**: If the action is mission-critical or widely reused, have an engineer reimplement it as a strongly-typed TypeScript action in an `@mj-biz-apps/*` package.
50
+
51
+ ---
52
+
53
+ ## 3. Deploying the Agent
54
+
55
+ ### Option 1: Commit to the Organization's Platform Repo (Recommended)
56
+ 1. Extract the metadata files into your organization's repository (e.g. `bc-platform/metadata/`).
57
+ 2. Commit and push the changes:
58
+ ```bash
59
+ git add metadata/
60
+ git commit -m "feat(agents): add InvoiceAuditAgent from citizen builder"
61
+ git push
62
+ ```
63
+ 3. Your CI/CD deployment pipeline will push the metadata to staging and production.
64
+
65
+ ### Option 2: Direct Sync Push to Target Instance
66
+ If deploying directly to a staging or production instance via CLI:
67
+ ```bash
68
+ mj sync push --dir /path/to/extracted/metadata
69
+ ```
70
+ The agent is now active and ready for end users.
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": "1.0",
3
+ "directories": [
4
+ "agents",
5
+ "prompts"
6
+ ]
7
+ }
@@ -0,0 +1,55 @@
1
+ [
2
+ {
3
+ "fields": {
4
+ "Name": "Customer Insight Specialist",
5
+ "CategoryID": "@lookup:MJ: AI Agent Categories.Name=Assistant",
6
+ "Description": "Deterministic flow agent that summarizes customer activity, evaluates account standing, and suggests next actions.",
7
+ "TypeID": "@lookup:MJ: AI Agent Types.Name=Flow",
8
+ "Status": "Active",
9
+ "ExecutionOrder": 0,
10
+ "ExposeAsAction": false,
11
+ "IconClass": "mj-icon-user-check",
12
+ "ArtifactCreationMode": "None",
13
+ "PayloadDownstreamPaths": "*",
14
+ "PayloadUpstreamPaths": "*",
15
+ "EnableContextCompression": false,
16
+ "ModelSelectionMode": "Agent Type"
17
+ },
18
+ "relatedEntities": {
19
+ "MJ: AI Agent Prompts": [
20
+ {
21
+ "fields": {
22
+ "AgentID": "@parent:ID",
23
+ "PromptID": "@lookup:MJ: AI Prompts.Name=Customer Insight Specialist Prompt",
24
+ "Status": "Active",
25
+ "ExecutionOrder": 1
26
+ },
27
+ "primaryKey": {
28
+ "ID": "E9A0C381-645F-4D2A-883F-E19C69D3B511"
29
+ }
30
+ }
31
+ ],
32
+ "MJ: AI Agent Steps": [
33
+ {
34
+ "fields": {
35
+ "AgentID": "@parent:ID",
36
+ "Name": "Generate Customer Insights",
37
+ "Description": "Evaluates account data using the Customer Insight Specialist Prompt",
38
+ "StepType": "Prompt",
39
+ "StartingStep": true,
40
+ "PromptID": "@lookup:MJ: AI Prompts.Name=Customer Insight Specialist Prompt",
41
+ "Status": "Active",
42
+ "PositionX": 100,
43
+ "PositionY": 100
44
+ },
45
+ "primaryKey": {
46
+ "ID": "D2E49B18-091A-4832-B81E-A38C91307D55"
47
+ }
48
+ }
49
+ ]
50
+ },
51
+ "primaryKey": {
52
+ "ID": "A7F01234-8899-4A1B-89E2-7722BCDEF001"
53
+ }
54
+ }
55
+ ]
@@ -0,0 +1,45 @@
1
+ {
2
+ "entity": "MJ: AI Agents",
3
+ "filePattern": "**/.*.json",
4
+ "defaults": {
5
+ "TypeID": "@lookup:MJ: AI Agent Types.Name=Flow",
6
+ "ModelSelectionMode": "Agent Type",
7
+ "ExposeAsAction": false,
8
+ "Status": "Active"
9
+ },
10
+ "pull": {
11
+ "createNewFileIfNotFound": true,
12
+ "newFileName": ".agents.json",
13
+ "appendRecordsToExistingFile": true,
14
+ "updateExistingRecords": true,
15
+ "preserveFields": [],
16
+ "excludeFields": [],
17
+ "mergeStrategy": "merge",
18
+ "backupBeforeUpdate": true,
19
+ "backupDirectory": ".backups",
20
+ "lookupFields": {
21
+ "TypeID": {
22
+ "entity": "MJ: AI Agent Types",
23
+ "field": "Name"
24
+ },
25
+ "CategoryID": {
26
+ "entity": "MJ: AI Agent Categories",
27
+ "field": "Name"
28
+ }
29
+ },
30
+ "relatedEntities": {
31
+ "MJ: AI Agent Prompts": {
32
+ "entity": "MJ: AI Agent Prompts",
33
+ "foreignKey": "AgentID"
34
+ },
35
+ "MJ: AI Agent Actions": {
36
+ "entity": "MJ: AI Agent Actions",
37
+ "foreignKey": "AgentID"
38
+ },
39
+ "MJ: AI Agent Steps": {
40
+ "entity": "MJ: AI Agent Steps",
41
+ "foreignKey": "AgentID"
42
+ }
43
+ }
44
+ }
45
+ }
@@ -0,0 +1,15 @@
1
+ [
2
+ {
3
+ "fields": {
4
+ "Name": "Customer Insight Specialist Prompt",
5
+ "Description": "Analyzes customer profile data and recent orders to provide executive account insights.",
6
+ "CategoryID": "@lookup:MJ: AI Prompt Categories.Name=Agent Type System Prompts",
7
+ "TypeID": "@lookup:MJ: AI Prompt Types.Name=Chat",
8
+ "Status": "Active",
9
+ "TemplateText": "@file:templates/customer-insight.template.md"
10
+ },
11
+ "primaryKey": {
12
+ "ID": "B1C90D1A-9321-4E18-912A-6844917B3C10"
13
+ }
14
+ }
15
+ ]
@@ -0,0 +1,45 @@
1
+ {
2
+ "entity": "MJ: AI Prompts",
3
+ "filePattern": "**/.*.json",
4
+ "defaults": {
5
+ "CategoryID": "@lookup:MJ: AI Prompt Categories.Name=Agent Type System Prompts?create&Description=Prompts for Custom Agents",
6
+ "TypeID": "@lookup:MJ: AI Prompt Types.Name=Chat"
7
+ },
8
+ "ignoreDirectories": [
9
+ "output",
10
+ "templates"
11
+ ],
12
+ "pull": {
13
+ "createNewFileIfNotFound": true,
14
+ "newFileName": ".prompts.json",
15
+ "appendRecordsToExistingFile": true,
16
+ "updateExistingRecords": true,
17
+ "ignoreNullFields": true,
18
+ "ignoreVirtualFields": true,
19
+ "preserveFields": [
20
+ "TemplateText"
21
+ ],
22
+ "excludeFields": [
23
+ "TemplateID"
24
+ ],
25
+ "mergeStrategy": "merge",
26
+ "backupBeforeUpdate": true,
27
+ "backupDirectory": ".backups",
28
+ "externalizeFields": [
29
+ {
30
+ "field": "TemplateText",
31
+ "pattern": "@file:templates/{Name}.template.md"
32
+ }
33
+ ],
34
+ "lookupFields": {
35
+ "CategoryID": {
36
+ "entity": "MJ: AI Prompt Categories",
37
+ "field": "Name"
38
+ },
39
+ "TypeID": {
40
+ "entity": "MJ: AI Prompt Types",
41
+ "field": "Name"
42
+ }
43
+ }
44
+ }
45
+ }
@@ -0,0 +1,18 @@
1
+ # Customer Insight Specialist Prompt
2
+
3
+ You are an expert customer account analyst. Your goal is to review customer profile data and order history, then synthesize a concise executive summary with actionable recommendations.
4
+
5
+ ## Instructions
6
+ 1. Analyze the customer account details, active status, and recent activity.
7
+ 2. Review any open orders or pending balances.
8
+ 3. Formulate 3 key insights:
9
+ - Account Health (engagement level and standing)
10
+ - Value / Purchase Pattern (frequent categories, average volume)
11
+ - Recommended Next Action (e.g. follow-up call, cross-sell recommendation, renewal notice)
12
+ 4. Maintain a professional, objective tone. Do not fabricate details not present in the input.
13
+
14
+ ## Output Format
15
+ Deliver your response formatted cleanly with the following markdown sections:
16
+ - **Executive Summary**
17
+ - **Key Metrics & Observations**
18
+ - **Actionable Recommendations**
@@ -0,0 +1,47 @@
1
+ #!/bin/bash
2
+ # ==============================================================================
3
+ # Citizen Agent Builder - Environment Bootstrap Script
4
+ # Runs inside the MJAPI container or via:
5
+ # docker compose exec api /work/scripts/bootstrap.sh
6
+ # ==============================================================================
7
+ set -e
8
+
9
+ echo "========================================================"
10
+ echo " Starting MemberJunction Citizen Builder Bootstrap"
11
+ echo "========================================================"
12
+
13
+ cd /app
14
+
15
+ # 1. Run core migrations
16
+ echo "[1/4] Ensuring core MemberJunction database migrations are applied..."
17
+ mj migrate
18
+
19
+ # 2. Install Open App (More Cheese by default, or Org-specific app)
20
+ APP_URL="${OPEN_APP_INSTALL_URL:-https://github.com/MemberJunction/more-cheese}"
21
+ echo "[2/4] Installing business context Open App: $APP_URL..."
22
+
23
+ if [ -n "$GITHUB_TOKEN" ]; then
24
+ # Inject token into GitHub URL if private repo
25
+ AUTH_APP_URL=$(echo "$APP_URL" | sed -E "s|https://github.com/|https://$GITHUB_TOKEN@github.com/|")
26
+ mj app install "$AUTH_APP_URL" || echo "Warning: mj app install returned non-zero, continuing..."
27
+ else
28
+ mj app install "$APP_URL" || echo "Warning: mj app install returned non-zero, continuing..."
29
+ fi
30
+
31
+ # 3. Generate Capabilities Catalog
32
+ echo "[3/4] Generating CAPABILITIES.md catalog from database..."
33
+ if [ -f "/work/scripts/generate-capabilities.sh" ]; then
34
+ bash /work/scripts/generate-capabilities.sh || echo "Warning: Capability generation skipped."
35
+ fi
36
+
37
+ # 4. Push local metadata
38
+ echo "[4/4] Pushing starter metadata to local instance..."
39
+ if [ -d "/work/metadata" ]; then
40
+ mj sync push --dir /work/metadata || echo "Initial sync completed or already up to date."
41
+ fi
42
+
43
+ echo "========================================================"
44
+ echo " MemberJunction Citizen Builder is Ready!"
45
+ echo " API: http://localhost:${API_PORT:-4000}"
46
+ echo " Database: localhost:${DB_PORT:-1433}"
47
+ echo "========================================================"
@@ -0,0 +1,184 @@
1
+ #!/bin/bash
2
+ # ==============================================================================
3
+ # MemberJunction Citizen Agent Builder - Container Entrypoint
4
+ # Automates first-time installation via `mj install`, database provisioning,
5
+ # Open App installation, and starts both MJAPI (:4000) and MJExplorer (:4200).
6
+ # ==============================================================================
7
+ set -e
8
+
9
+ echo "========================================================================"
10
+ echo " Starting MemberJunction Runtime Container"
11
+ echo "========================================================================"
12
+
13
+ DB_HOST="${DB_HOST:-sqlserver}"
14
+ DB_PORT="${DB_PORT:-1433}"
15
+ DB_PASSWORD="${DB_PASSWORD:-TestPassword123!}"
16
+ DB_DATABASE="${DB_DATABASE:-MemberJunction}"
17
+
18
+ # 1. Wait for SQL Server to be accessible
19
+ echo "Waiting for SQL Server ($DB_HOST:$DB_PORT) to be ready..."
20
+ until node -e "
21
+ const net = require('net');
22
+ const client = net.connect($DB_PORT, '$DB_HOST', () => {
23
+ client.destroy();
24
+ process.exit(0);
25
+ });
26
+ client.on('error', () => process.exit(1));
27
+ setTimeout(() => process.exit(1), 2000);
28
+ " 2>/dev/null; do
29
+ echo " Waiting for database connection..."
30
+ sleep 3
31
+ done
32
+ echo "SQL Server is reachable!"
33
+
34
+ cd /workspace
35
+
36
+ # 2. First-time setup: install MemberJunction if not already installed
37
+ if [ ! -f "/workspace/package.json" ]; then
38
+ echo ""
39
+ echo "========================================================================"
40
+ echo " First-Time Setup: Installing MemberJunction via 'mj install'..."
41
+ echo " This runs once and initializes your database, API, and Explorer."
42
+ echo "========================================================================"
43
+
44
+ # Generate install configuration
45
+ cat << EOF > /tmp/install.config.json
46
+ {
47
+ "PackageManager": "pnpm",
48
+ "dbUrl": "$DB_HOST",
49
+ "dbInstance": "",
50
+ "dbTrustServerCertificate": "Y",
51
+ "dbDatabase": "$DB_DATABASE",
52
+ "dbPort": $DB_PORT,
53
+ "codeGenLogin": "sa",
54
+ "codeGenPwD": "$DB_PASSWORD",
55
+ "mjAPILogin": "sa",
56
+ "mjAPIPwD": "$DB_PASSWORD",
57
+ "graphQLPort": 4000,
58
+ "authType": "Local",
59
+ "createNewUser": "Y",
60
+ "userEmail": "admin@memberjunction.org",
61
+ "userFirstName": "Admin",
62
+ "userLastName": "User",
63
+ "userName": "admin",
64
+ "openAIAPIKey": "${AI_VENDOR_API_KEY__OpenAILLM:-}",
65
+ "anthropicAPIKey": "${AI_VENDOR_API_KEY__AnthropicLLM:-}",
66
+ "geminiAPIKey": "${AI_VENDOR_API_KEY__GeminiLLM:-}"
67
+ }
68
+ EOF
69
+
70
+ # Execute headless install
71
+ mj install --yes --fast --config /tmp/install.config.json --dir /workspace
72
+ pnpm add -w @angular/compiler@21.2.22 2>/dev/null || true
73
+
74
+ # Install Open App business context (More Cheese default or custom enterprise app)
75
+ APP_URL="${OPEN_APP_INSTALL_URL:-https://github.com/MemberJunction/more-cheese}"
76
+ echo "Installing business context Open App: $APP_URL..."
77
+ if [ -n "$GITHUB_TOKEN" ]; then
78
+ AUTH_APP_URL=$(echo "$APP_URL" | sed -E "s|https://github.com/|https://$GITHUB_TOKEN@github.com/|")
79
+ mj app install "$AUTH_APP_URL" || echo "Notice: mj app install completed or skipped."
80
+ else
81
+ mj app install "$APP_URL" || echo "Notice: mj app install completed or skipped."
82
+ fi
83
+
84
+ # Generate capabilities catalog
85
+ if [ -f "/work/scripts/generate-capabilities.sh" ]; then
86
+ bash /work/scripts/generate-capabilities.sh || echo "Notice: Capabilities generation completed."
87
+ fi
88
+
89
+ # Push starter metadata
90
+ if [ -d "/work/metadata" ]; then
91
+ mj sync push --dir /work/metadata || echo "Notice: Initial metadata push completed."
92
+ fi
93
+
94
+ echo "MemberJunction installation and provisioning complete!"
95
+ else
96
+ echo "Existing MemberJunction workspace detected in /workspace."
97
+ # Apply any pending migrations
98
+ mj migrate || echo "Database migrations up to date."
99
+ fi
100
+
101
+ # Configure MJExplorer host binding and compiler alignment
102
+ if [ -f "apps/MJExplorer/package.json" ]; then
103
+ node -e "
104
+ const fs = require('fs');
105
+ const p = 'apps/MJExplorer/package.json';
106
+ const pkg = JSON.parse(fs.readFileSync(p, 'utf8'));
107
+ let changed = false;
108
+ if (pkg.scripts && pkg.scripts.start && !pkg.scripts.start.includes('--host 0.0.0.0')) {
109
+ pkg.scripts.start = pkg.scripts.start.replace('ng serve', 'ng serve --host 0.0.0.0 --port 4200');
110
+ changed = true;
111
+ }
112
+ const cliVer = (pkg.devDependencies && pkg.devDependencies['@angular/compiler-cli']) || '21.2.22';
113
+ if (pkg.dependencies && pkg.dependencies['@angular/compiler'] !== cliVer) {
114
+ pkg.dependencies['@angular/compiler'] = cliVer;
115
+ changed = true;
116
+ }
117
+ if (changed) {
118
+ fs.writeFileSync(p, JSON.stringify(pkg, null, 2));
119
+ }
120
+ "
121
+ fi
122
+
123
+ # Sanitize dynamicPackages.client so non-browser packages are not bundled into MJExplorer
124
+ if [ -f "mj.config.cjs" ]; then
125
+ node -e "
126
+ const fs = require('fs');
127
+ try {
128
+ const config = require('./mj.config.cjs');
129
+ if (config.dynamicPackages && Array.isArray(config.dynamicPackages.client)) {
130
+ let changed = false;
131
+ config.dynamicPackages.client.forEach(entry => {
132
+ if (!entry.PackageName.endsWith('-ng') || entry.PackageName === '@mj-biz-apps/sonar-ng') {
133
+ if (entry.Enabled !== false) {
134
+ entry.Enabled = false;
135
+ changed = true;
136
+ }
137
+ }
138
+ });
139
+ if (changed) {
140
+ let code = fs.readFileSync('mj.config.cjs', 'utf8');
141
+ const regex = /client:\s*\[[\s\S]*?\]\s*\},/m;
142
+ code = code.replace(regex, 'client: ' + JSON.stringify(config.dynamicPackages.client, null, 2) + '\n },');
143
+ fs.writeFileSync('mj.config.cjs', code);
144
+ }
145
+ }
146
+ } catch (e) {
147
+ console.warn('Notice: dynamicPackages check skipped:', e.message);
148
+ }
149
+ "
150
+ fi
151
+
152
+ # 3. Start MJAPI and MJExplorer services via PM2
153
+ echo "Starting MJAPI and MJExplorer services..."
154
+ pm2 delete all 2>/dev/null || true
155
+
156
+ # Start API service
157
+ if [ -f "package.json" ]; then
158
+ if grep -q "start:api" package.json; then
159
+ pm2 start "npm run start:api" --name mjapi
160
+ elif [ -d "apps/MJAPI" ]; then
161
+ pm2 start "cd apps/MJAPI && npm start" --name mjapi
162
+ else
163
+ pm2 start "npm start" --name mjapi
164
+ fi
165
+ fi
166
+
167
+ # Start Explorer service
168
+ if [ -f "package.json" ]; then
169
+ if grep -q "start:explorer" package.json; then
170
+ pm2 start "npm run start:explorer" --name mjexplorer
171
+ elif [ -d "apps/MJExplorer" ]; then
172
+ pm2 start "cd apps/MJExplorer && npm start" --name mjexplorer
173
+ fi
174
+ fi
175
+
176
+ echo "========================================================================"
177
+ echo " 🎉 MemberJunction Stack is Running!"
178
+ echo " MJAPI: http://localhost:4000 (GraphQL & API)"
179
+ echo " MJExplorer: http://localhost:4200 (Web Interface)"
180
+ echo " Database: localhost:$DB_PORT (DB: $DB_DATABASE)"
181
+ echo "========================================================================"
182
+
183
+ # Keep container running and stream logs
184
+ exec pm2 logs
@@ -0,0 +1,74 @@
1
+ #!/bin/bash
2
+ # ==============================================================================
3
+ # Citizen Agent Builder - Capabilities Catalog Generator
4
+ # Queries the local MemberJunction database and outputs an updated CAPABILITIES.md
5
+ # so the local coding agent has an exact catalog of entities, actions, and agents.
6
+ # ==============================================================================
7
+ set -e
8
+
9
+ DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
10
+ OUTPUT_FILE="$DIR/CAPABILITIES.md"
11
+
12
+ if [ -f "$DIR/.env" ]; then
13
+ set -a
14
+ source "$DIR/.env"
15
+ set +a
16
+ fi
17
+
18
+ DB_PASSWORD="${DB_PASSWORD:-TestPassword123!}"
19
+
20
+ echo "Generating CAPABILITIES.md from database catalog..."
21
+
22
+ SQL_QUERY="
23
+ SET NOCOUNT ON;
24
+ PRINT '# System Capabilities Catalog';
25
+ PRINT '';
26
+ PRINT 'This catalog reflects the real entities, actions, and agents available in this MemberJunction instance.';
27
+ PRINT 'Use these exact names when authoring agent steps, action bindings, and prompt templates.';
28
+ PRINT '';
29
+ PRINT '## 1. Available Entities';
30
+ PRINT '| Entity Name | Description |';
31
+ PRINT '|---|---|';
32
+ SELECT '| \`' + Name + '\` | ' + REPLACE(REPLACE(COALESCE(Description, 'No description'), CHAR(13), ' '), CHAR(10), ' ') + ' |'
33
+ FROM [__mj].[vwEntities]
34
+ WHERE VirtualEntity = 0
35
+ ORDER BY Name ASC;
36
+
37
+ PRINT '';
38
+ PRINT '## 2. Available Actions (Tools)';
39
+ PRINT '| Action Name | Description |';
40
+ PRINT '|---|---|';
41
+ SELECT '| \`' + Name + '\` | ' + REPLACE(REPLACE(COALESCE(Description, 'No description'), CHAR(13), ' '), CHAR(10), ' ') + ' |'
42
+ FROM [__mj].[vwActions]
43
+ ORDER BY Name ASC;
44
+
45
+ PRINT '';
46
+ PRINT '## 3. Available Sub-Agents';
47
+ PRINT '| Agent Name | Type | Description |';
48
+ PRINT '|---|---|---|';
49
+ SELECT '| \`' + Name + '\` | ' + Type + ' | ' + REPLACE(REPLACE(COALESCE(Description, 'No description'), CHAR(13), ' '), CHAR(10), ' ') + ' |'
50
+ FROM [__mj].[vwAIAgents]
51
+ ORDER BY Name ASC;
52
+ "
53
+
54
+ docker compose exec -T sqlserver /opt/mssql-tools18/bin/sqlcmd \
55
+ -S localhost -U sa -P "$DB_PASSWORD" -d MemberJunction -C -No -W -w 200 \
56
+ -Q "$SQL_QUERY" > "$OUTPUT_FILE" 2>/dev/null || {
57
+ echo "Notice: Database not yet initialized; creating baseline CAPABILITIES.md"
58
+ cat << 'EOF' > "$OUTPUT_FILE"
59
+ # System Capabilities Catalog
60
+
61
+ *This catalog is automatically populated once your local database is booted and bootstrapped.*
62
+
63
+ ## Available Core Actions
64
+ * `Send Email` - Send notification or transactional emails
65
+ * `Create Record` - Insert a new record into any permitted entity
66
+ * `Update Record` - Update an existing record by ID
67
+ * `Run Query` - Execute a dynamic query against entities
68
+ * `Get Record` - Fetch a record by primary key
69
+
70
+ Run `./scripts/bootstrap.sh` to populate the complete catalog from your installed Open App.
71
+ EOF
72
+ }
73
+
74
+ echo "Capabilities catalog updated at: $OUTPUT_FILE"