@atlashub/smartstack-cli 3.52.0 → 3.54.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlashub/smartstack-cli",
3
- "version": "3.52.0",
3
+ "version": "3.54.0",
4
4
  "description": "SmartStack Claude Code automation toolkit - GitFlow, EF Core migrations, prompts and more",
5
5
  "author": {
6
6
  "name": "SmartStack",
@@ -10,12 +10,17 @@ tools: Bash, Read, Write, Glob, AskUserQuestion
10
10
 
11
11
  You initialize a GitFlow project by orchestrating 3 specialized sub-agents.
12
12
 
13
+ **IMPORTANT: User questions (root folder, project name, worktree mode) are normally
14
+ handled by the main conversation BEFORE this agent is spawned. If you receive
15
+ pre-confirmed values in your prompt, use them directly. If values are NOT provided,
16
+ you MUST call AskUserQuestion for each missing value before proceeding.**
17
+
13
18
  ## ARCHITECTURE
14
19
 
15
20
  ```
16
21
  gitflow-init (you - orchestrator)
17
22
  ├── Task(gitflow-init-detect) → Environment report
18
- ├── AskUserQuestion → User confirms URL, path, name, worktree mode
23
+ ├── AskUserQuestion → ONLY if values not pre-confirmed by caller
19
24
  ├── Task(gitflow-init-clone) → Create structure (skip if disabled)
20
25
  ├── Write config.json → v2.1.0 with platform & workspace
21
26
  └── Task(gitflow-init-validate) → Verify & repair (skip if disabled)
@@ -1390,3 +1390,29 @@ public class {Module}DevDataSeeder : IDevDataSeeder
1390
1390
  > **Pipeline validation:**
1391
1391
  > - ralph-loop POST-CHECK warns if GUID not found in project config
1392
1392
  > - validate-feature step-05 verifies FK exists in real database via SQL query
1393
+
1394
+ ---
1395
+
1396
+ ## DataExportEndpoint Seed Data Pattern
1397
+
1398
+ When adding a new export endpoint, add seed data in `DataExportEndpointConfiguration.cs`:
1399
+
1400
+ ```csharp
1401
+ builder.HasData(new {
1402
+ Id = new Guid("{random-guid}"),
1403
+ NavigationApplicationId = NavigationApplicationSeedData.{App}AppId,
1404
+ NavigationModuleId = NavigationModuleSeedData.{Module}ModuleId,
1405
+ Code = "{entity-code}",
1406
+ Name = "{Entity} Export",
1407
+ Description = "Export {entity} data with metadata",
1408
+ RouteTemplate = "/api/v1/export/{entity-code}",
1409
+ RequiredPermission = "{app}.{module}.export",
1410
+ EntityType = "{Entity}",
1411
+ IsActive = true,
1412
+ DefaultRateLimitPerMinute = 60,
1413
+ DefaultMaxPageSize = 1000,
1414
+ CreatedAt = seedDate
1415
+ });
1416
+ ```
1417
+
1418
+ Requires matching controller in `Controllers/DataExport/v1/Export{Entity}Controller.cs`.
@@ -810,6 +810,40 @@ services.AddValidatorsFromAssemblyContaining<Create{Name}DtoValidator>();
810
810
 
811
811
  ---
812
812
 
813
+ ## External Application & Data Export Pattern
814
+
815
+ ### Entities
816
+
817
+ | Entity | Table | Description |
818
+ |--------|-------|-------------|
819
+ | `ExternalApplication` | `auth_ExternalApplications` | Machine-to-machine API account (ClientId, ClientSecret, IsActive, IP whitelist) |
820
+ | `ExternalApplicationRole` | `auth_ExternalApplicationRoles` | Role assignment per app (AppId, RoleId, optional TenantId) |
821
+ | `ExternalApplicationExportAccess` | `auth_ExternalApplicationExportAccesses` | Per-app access to specific export endpoint (IsEnabled, RateLimitPerMinute, MaxPageSize) |
822
+ | `DataExportEndpoint` | `auth_DataExportEndpoints` | Registry of available export APIs (Code, RouteTemplate, RequiredPermission, EntityType) |
823
+ | `ExternalAppAuditLog` | `auth_ExternalAppAuditLogs` | Audit trail for all API calls (Authentication, DataExport actions) |
824
+
825
+ ### Architecture (3-layer security)
826
+
827
+ 1. **Authentication** — JWT assertion signed with ClientSecret → ExternalApplicationAuthService validates → generates SmartStack JWT with permissions resolved via ExternalApplicationRole → Role → RolePermission chain
828
+ 2. **Authorization** — RequirePermissionFilter checks JWT claims (e.g., `administration.users.export`)
829
+ 3. **Access Control** — DataExportAccessMiddleware verifies per-app endpoint access in ExternalApplicationExportAccess table
830
+
831
+ ### Rate Limiting
832
+
833
+ ExternalAppRateLimitPolicy resolves limits: app override → endpoint default → 60/min fallback.
834
+ Partition key: `{clientId}:{endpointCode}`.
835
+
836
+ ### Seed Data
837
+
838
+ DataExportEndpoints are seeded in DataExportEndpointConfiguration.cs with FK to NavigationApplication and NavigationModule. Each endpoint maps to a controller in `Controllers/DataExport/v1/`.
839
+
840
+ ### Controller Pattern
841
+
842
+ Export controllers: `[Route("api/v1/export")]` + `[RequirePermission]` + `[EnableRateLimiting]`
843
+ Management controllers: `[NavRoute("api.accounts")]` with CustomSegment
844
+
845
+ ---
846
+
813
847
  ## PaginatedResult Pattern
814
848
 
815
849
  > **Canonical type for ALL paginated responses.** One name, one contract, everywhere.
@@ -19,6 +19,7 @@
19
19
  | `support.*` | `support_` | `Support` | Table: `support_Tickets`, Controller: `Controllers/Support/TicketsController.cs` |
20
20
  | `*` (business apps) | `ref_` or domain-specific | `{ApplicationPascal}` | Table: `ref_Products`, Controller: `Controllers/Sales/ProductsController.cs` |
21
21
  | `myspace.*` | `usr_` | `MySpace` | Table: `usr_Preferences`, Controller: `Controllers/MySpace/PreferencesController.cs` |
22
+ | `api.*` | `auth_` or `ext_` | `Api` | Table: `auth_ExternalApplications`, Controller: `Controllers/Platform/Api/ExternalApplications/` |
22
23
 
23
24
  ---
24
25
 
@@ -26,6 +26,7 @@ Suggests companion modules based on primary module type:
26
26
  | **Permissions/Security** | permission, role, access, authority, rbac | UserRoles, Groups, Policies, Audit, Delegation | Permission systems need fine-grained control, group policies, and audit trails |
27
27
  | **Notifications** | notification, alert, email, message, broadcast | Templates, Channels, Scheduling, Preferences | Notification systems need template management, multi-channel support, scheduling |
28
28
  | **Reporting** | report, dashboard, analytics, BI, metrics | Dashboards, Exports, Scheduling, AlertRules | Reporting needs visualization, scheduled distribution, and data export |
29
+ | **API Management / Integrations** | api, external, integration, webhook, export, data-export, machine-to-machine | ExternalApps, DataExportEndpoints, ExportAccess, AuditLogs, ApiKeys | API platforms need app registration, key management, granular endpoint access, rate limiting, and audit logging |
29
30
 
30
31
  ---
31
32
 
@@ -66,6 +67,7 @@ Suggests system integrations based on requirements:
66
67
  | **Geographical features** | Maps/Location Service | Spatial data handling | Add section with provider selection, geocoding, distance calculation |
67
68
  | **Data synchronization** | Event Bus/Messaging | Async data consistency | Add section with message types, subscription strategy, retry logic |
68
69
  | **File storage** | Cloud Storage Integration | Large file handling | Add section with provider selection, access control, cleanup policy |
70
+ | **Machine-to-machine API** | External app, M2M, JWT assertion, API key | Data Export API | Add section with app registration, key generation, endpoint-level access grants, per-app rate limits, and audit log |
69
71
 
70
72
  ---
71
73
 
@@ -185,7 +185,7 @@ start ──► commit* ──► sync ──► pr ──► merge ──► fi
185
185
 
186
186
  | Input Pattern | Step File | Task Agent (`subagent_type`) |
187
187
  |---------------|-----------|----------------------------|
188
- | `init` | `steps/step-init.md` | `gitflow-init` |
188
+ | `init` | `steps/step-init.md` | **ALWAYS INLINE** (see below) |
189
189
  | `start`, `-f`, `-r`, `-h` | `steps/step-start.md` | `gitflow-start` |
190
190
  | `commit [msg]` | `steps/step-commit.md` | `gitflow-commit` |
191
191
  | `sync` | `steps/step-sync.md` | — |
@@ -206,6 +206,16 @@ start ──► commit* ──► sync ──► pr ──► merge ──► fi
206
206
  | **Auto mode** (`-a`) | Use `Task` tool with the matching `subagent_type` for each step sequentially |
207
207
  | **Standalone phases** | Always delegate to Task agent (fast, isolated) |
208
208
 
209
+ **⚠️ SPECIAL RULE FOR `init`:**
210
+ `init` is **ALWAYS executed inline** — NEVER delegate to a Task agent.
211
+ Read `steps/step-init.md` and execute it directly in the main conversation.
212
+ This is mandatory because `init` requires AskUserQuestion calls that MUST
213
+ happen in the main conversation (sub-agents skip questions).
214
+ After the user answers all questions, delegate heavy work to:
215
+ - `Task(gitflow-init-detect)` for environment detection
216
+ - `Task(gitflow-init-clone)` for structure creation
217
+ - `Task(gitflow-init-validate)` for post-init verification
218
+
209
219
  </entry_point>
210
220
 
211
221
  <step_files>
@@ -10,134 +10,106 @@ next_step: null
10
10
 
11
11
  Set up GitFlow configuration with bare repository, worktrees, and branches.
12
12
 
13
- **ULTRA THINK before creating configuration.**
14
-
15
- ---
16
-
17
- ## MANDATORY INTERACTIVE QUESTIONS
18
-
19
- ╔══════════════════════════════════════════════════════════════════════════╗
20
- ║ You MUST call AskUserQuestion for EACH question below. ║
21
- ║ Auto-detected values are SUGGESTIONS for option labels, NOT answers. ║
22
- ║ NEVER use a detected value as the final value without user confirm. ║
23
- ║ Minimum AskUserQuestion calls: 3 (if URL provided) or 4 (if not). ║
24
- ╚══════════════════════════════════════════════════════════════════════════╝
25
-
26
- | Question | Variable | Suggested from | MUST ASK? |
27
- |----------|----------|----------------|-----------|
28
- | Repository URL | `{REPO_URL}` | `git remote get-url origin` | YES (skip only if URL in command args) |
29
- | Root folder | `{ROOT_FOLDER}` | Parent of current directory | **ALWAYS YES** |
30
- | Project name | `{PROJECT_NAME}` | Repo name from URL or folder | **ALWAYS YES** |
31
- | Worktree mode | `{WORKTREE_MODE}` | None — no default | **ALWAYS YES** |
32
-
33
- **Multi-project principle:** Each repository has its OWN independent GitFlow config. Step 2 scans for sibling projects to provide context, not to share configuration.
34
-
35
- **⛔ FOLLOW-UP RULE:** When a user selects a "Custom..." option (custom name, custom path, custom URL), that selection is just a CHOICE, not the actual value. You MUST immediately ask a follow-up question to capture the actual value. Never proceed with a blank or default value.
13
+ **This step runs INLINE in the main conversation. All AskUserQuestion calls
14
+ happen here (NOT in a sub-agent). Only clone/validate are delegated.**
36
15
 
37
16
  ---
38
17
 
39
18
  ## EXECUTION SEQUENCE:
40
19
 
41
- ### 1. Detect Environment (for defaults only)
42
-
43
- See [references/init-environment-detection.md](../references/init-environment-detection.md) for:
44
- - Platform detection (WSL/Windows/macOS/Linux)
45
- - Git provider detection
46
- - Auto-detect defaults (URL, folder, project name)
47
-
48
- ### 2. Detect Workspace (multi-project context)
49
-
50
- See [references/init-workspace-detection.md](../references/init-workspace-detection.md) for:
51
- - Sibling project scanning
52
- - Workspace context display
53
- - Per-repository GitFlow principle
20
+ ### 1. Detect Environment (delegate to sub-agent)
54
21
 
55
- ### 3. Question: Existing Configuration
22
+ Spawn `Task(gitflow-init-detect)` (haiku) to detect platform, git state, workspace siblings, provider.
23
+ Parse the report to extract: PLATFORM, SHELL_TYPE, DETECTED_URL, DETECTED_NAME, GIT_PROVIDER, SIBLING_COUNT.
56
24
 
57
- **⛔ Only if `ALREADY_INITIALIZED` = true.** Otherwise skip to step 4.
25
+ ### 2. Check Existing Configuration
58
26
 
59
- See [references/init-questions.md](../references/init-questions.md) **Question 4** for options (Reconfigure / Repair / View only / Cancel).
27
+ If `.claude/gitflow/config.json` exists, ask user: Reconfigure / Repair / View / Cancel.
28
+ If Cancel or View → EXIT. If Repair → delegate to `Task(gitflow-init-validate)` → EXIT.
60
29
 
61
- ### 4. Question: Repository URL
30
+ ### 3. Question: Repository URL
62
31
 
63
- **⛔ MUST ASK even if URL was auto-detected.**
32
+ If URL was provided in command args (starts with `https://` or `git@`), use it directly → skip to step 4.
64
33
 
65
- See [references/init-questions.md](../references/init-questions.md) → **Question 1** for format and follow-up rules.
34
+ Otherwise, call AskUserQuestion:
35
+ - header: "Repository"
36
+ - question: "Repository URL? (detected: {DETECTED_URL})"
37
+ - options: Use detected URL (Recommended) / Enter GitHub URL / Enter Azure DevOps URL / Local only
38
+ - If user selects custom option → ask follow-up for actual URL
66
39
 
67
- ### 5. Question: Root Folder — CALL AskUserQuestion
40
+ Store as `{REPO_URL}`.
68
41
 
69
- **CALL AskUserQuestion NOW. Do NOT auto-derive from the URL or environment.**
42
+ ### 4. Question: Root Folder
70
43
 
71
- See [references/init-questions.md](../references/init-questions.md) → **Question 2** for format and follow-up rules.
44
+ Call AskUserQuestion:
45
+ - header: "Location"
46
+ - question: "Root folder for this project? (worktrees will be created here)"
47
+ - options:
48
+ - "Use parent folder (Recommended)" — "{PARENT_DIR}/ - consistent with {SIBLING_COUNT} sibling project(s)"
49
+ - "Use current folder" — "{CURRENT_DIR}/"
50
+ - "Custom path" — "Specify a different location"
51
+ - If user selects "Custom path" → ask follow-up for actual path
72
52
 
73
- ### 6. Question: Project Name CALL AskUserQuestion
53
+ Store as `{PROJECT_BASE}`. Normalize for platform (WSL: /mnt/ format, Windows: forward slashes).
74
54
 
75
- **CALL AskUserQuestion NOW. Do NOT auto-derive from the URL or environment.**
55
+ ### 5. Question: Project Name
76
56
 
77
- See [references/init-questions.md](../references/init-questions.md) → **Question 3** for format and follow-up rules.
57
+ Call AskUserQuestion:
58
+ - header: "Project"
59
+ - question: "Project name? (detected: {DETECTED_NAME})"
60
+ - options:
61
+ - "Use detected name (Recommended)" — "{DETECTED_NAME}"
62
+ - "Custom name" — "Specify a different project name"
63
+ - If user selects "Custom name" → ask follow-up for actual name
78
64
 
79
- ### 6b. Normalize Project Name (INTELLIGENT)
65
+ Store as `{PROJECT_NAME}`.
80
66
 
81
- **⛔ ALWAYS normalize, even if user chose the detected name.**
67
+ Then normalize into variants: PascalCase.Dot, PascalCase, kebab-case, snake_case, Display Name.
68
+ See [references/init-name-normalization.md](../references/init-name-normalization.md).
82
69
 
83
- See [references/init-name-normalization.md](../references/init-name-normalization.md) for the full 5-step process:
84
- 1. Parse input into words (split on separators + camelCase)
85
- 2. Language detection and spell check (ask user if typos found)
86
- 3. Generate all name variants (PascalCase.Dot, PascalCase, kebab-case, snake_case)
87
- 4. Ask user to choose PRIMARY format
88
- 5. Store all derived names in `PROJECT_VARIANTS`
70
+ ### 6. Question: Worktree Mode
89
71
 
90
- ### 7. Question: Worktree Mode — CALL AskUserQuestion
72
+ Call AskUserQuestion:
73
+ - header: "Worktrees"
74
+ - question: "How should worktrees be organized?"
75
+ - options:
76
+ - "Organized (Recommended)" — "Numbered folders: 01-Main/, 02-Develop/, features/, releases/, hotfixes/"
77
+ - "Simple" — "Plain folders: main/, develop/, features/, releases/, hotfixes/"
78
+ - "Disabled" — "No worktrees, use git checkout (not recommended)"
91
79
 
92
- **CALL AskUserQuestion NOW. This question is the MOST FREQUENTLY SKIPPED.**
80
+ Store as `{WORKTREE_MODE}` ("organized", "simple", or "disabled").
93
81
 
94
- BLOCKING: If you reach step 8 without having called AskUserQuestion for
95
- worktree mode and received an explicit user answer, STOP and ask it NOW.
96
- Do NOT default to "organized". The user MUST choose.
82
+ ### 7. Confirm all values
97
83
 
98
- See [references/init-questions.md](../references/init-questions.md) **Question 5** for options:
99
- - **Organized** (recommended): `01-Main/`, `02-Develop/`, `features/`, `releases/`, `hotfixes/`
100
- - **Simple**: `main/`, `develop/`, `features/`, `releases/`, `hotfixes/`
101
- - **Disabled**: No worktrees, use `git checkout`
102
-
103
-
104
- ### 8. Create Directory Structure
105
-
106
- See [references/init-structure-creation.md](../references/init-structure-creation.md) for:
107
- - Path normalization for WSL
108
- - Complete directory structure creation with absolute paths
109
- - Bare repository setup
110
- - Worktree creation (organized and simple modes)
111
- - GitFlow config directory creation
112
-
113
- ### 9. Detect Version
114
-
115
- **⛔ MUST run BEFORE creating config.json (step 10) — the detected `{VERSION}` is needed in the config template.**
116
-
117
- See [references/init-version-detection.md](../references/init-version-detection.md) for:
118
- - Version detection with priority (csproj, package.json, tags, etc.)
119
- - Platform-agnostic path handling
120
- - Fallback: `0.0.0` if no version source found
121
-
122
- **⛔ WARNING:** Do NOT confuse the config schema version (`"version": "2.1.0"` at line 1 of config.json) with the project version (`"versioning.current": "{VERSION}"`). They are completely different values.
84
+ Display a summary to the user before proceeding:
85
+ ```
86
+ Ready to initialize:
87
+ URL: {REPO_URL}
88
+ Folder: {PROJECT_BASE}
89
+ Name: {PROJECT_NAME}
90
+ Mode: {WORKTREE_MODE}
91
+ ```
123
92
 
124
- ### 10. Create Configuration
93
+ ### 8. Create Directory Structure (delegate to sub-agent)
125
94
 
126
- **Write `.claude/gitflow/config.json` in develop worktree using the `{VERSION}` detected in step 9.**
95
+ **Skip if `{WORKTREE_MODE}` is "disabled".**
127
96
 
128
- See [references/init-config-template.md](../references/init-config-template.md) for:
129
- - Full config.json v2.1.0 template (platform, workspace, repository, git, worktrees, versioning, efcore, workflow, language)
130
- - Path storage convention (`normalize_path_for_storage()` format)
97
+ Spawn `Task(gitflow-init-clone)` (sonnet) with the user-confirmed values:
98
+ - REPO_URL, PROJECT_BASE, PROJECT_NAME, WORKTREE_MODE, PLATFORM
131
99
 
132
- **⛔ IMPORTANT:** Store paths using Windows-style format (`D:/path/to/folder`). The `read_gitflow_config()` in `_shared.md` translates to platform format at read time.
100
+ See [references/init-structure-creation.md](../references/init-structure-creation.md) for details.
133
101
 
134
- ### 10b. Post-Init Validation
102
+ ### 9. Detect Version + Create Configuration
135
103
 
136
- **⛔ MANDATORY: Verify the structure was created correctly.**
104
+ Detect version (csproj > package.json > tags > fallback `0.0.0`).
105
+ Write `.claude/gitflow/config.json` in develop worktree.
106
+ See [references/init-config-template.md](../references/init-config-template.md) for template.
107
+ Store paths as `D:/path/to/folder` format.
137
108
 
138
- See [references/init-config-template.md](../references/init-config-template.md) — Section "Post-Init Validation" for the full bash validation script.
109
+ ### 10. Post-Init Validation (delegate to sub-agent)
139
110
 
140
- Checks: .bare/HEAD, worktree branches (main/develop), features/releases/hotfixes dirs, .claude/gitflow/ dir.
111
+ Spawn `Task(gitflow-init-validate)` (haiku) to verify structure.
112
+ Checks: .bare/HEAD, worktree branches, directories, config file.
141
113
 
142
114
  ### 11. Summary
143
115
 
@@ -205,7 +177,7 @@ Before completing init, verify:
205
177
 
206
178
  ## SUCCESS CRITERIA:
207
179
 
208
- - ✅ AskUserQuestion tool called at least 3 times (4 if URL not in command args)
180
+ - ✅ AskUserQuestion called for root folder, project name, AND worktree mode
209
181
  - ✅ Complete folder structure created
210
182
  - ✅ Both main and develop worktrees functional
211
183
  - ✅ Configuration file created