@codemieai/cdk 0.1.270

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,2856 @@
1
+ # Codemie Infrastructure as Code
2
+
3
+ Infrastructure as Code solution for managing Codemie AI assistants, datasources, and workflows through declarative YAML configuration.
4
+
5
+ ## 🎯 What This Solves
6
+
7
+ ### Key Problems
8
+
9
+ **1. Access Control Limitations** 🔒
10
+ In Codemie UI, only resource creators can modify assistants and workflows. Team members cannot contribute improvements even when they have ideas.
11
+
12
+ **2. Limited Execution History Visibility** 👁️
13
+ Only the creator can see execution history of assistants and workflows - even administrators lack access. This makes debugging and monitoring difficult for the team.
14
+
15
+ **3. No Custom Validation** ✅
16
+ Changes go live immediately without additional checks. There's no way to enforce team-specific validation rules or quality gates before deployment.
17
+
18
+ ### What IaC Enables
19
+
20
+ **Democratic Access**
21
+ Anyone can propose changes via pull requests. Changes are reviewed and deployed by a service account with full access to all resources and their execution history.
22
+
23
+ **Custom Validation Pipeline**
24
+ Add your own validation rules in CI/CD - from simple YAML checks to AI-powered prompt reviews. Nothing deploys until it passes your criteria.
25
+
26
+ **Team Visibility**
27
+ Service account has access to execution history of all assistants and workflows, enabling team-wide monitoring, debugging, and analytics.
28
+
29
+ ### Additional Benefits
30
+
31
+ - **Code Review Process** - Changes reviewed before going live, improving quality
32
+ - **DRY Configuration** - `$ref` mechanism eliminates duplication (define once, use everywhere)
33
+ - **Automated Deployment** - CI/CD integration removes manual steps and human errors
34
+ - **Audit Trail** - Git history shows who changed what and why
35
+ - **Environment Consistency** - Same configuration can be deployed to dev/staging/prod or can be used by other teams
36
+
37
+ ## Overview
38
+
39
+ This IaC solution enables version-controlled, reproducible deployment of Codemie resources using a GitOps approach. Changes are detected via SHA256 checksums, and resources are managed by their human-readable names.
40
+
41
+ ## Installation
42
+
43
+ ```bash
44
+ npm install
45
+ ```
46
+
47
+ ### Environment Variables
48
+
49
+ Create a `.env` file in the project root:
50
+
51
+ ```bash
52
+ CODEMIE_API_URL=https://your-instance.codemie.ai/api
53
+ CODEMIE_AUTH_URL=https://your-keycloak.auth.com
54
+ CODEMIE_REALM=codemie
55
+ CODEMIE_CLIENT_ID=your-client-id
56
+ CODEMIE_CLIENT_SECRET=your-client-secret
57
+ ```
58
+
59
+ **⚠️ Security: DO NOT commit `.env` to Git!**
60
+
61
+ The `.env` file is already added to `.gitignore` and should never be committed to the repository.
62
+
63
+ **For local development:**
64
+ - Each developer creates their own `.env` file locally with actual credentials
65
+ - Copy the template above and replace with your values
66
+ - Use your own credentials (do not share them via Git)
67
+ - Optional: Create `.env.example` in your project (template without actual secrets) to help team members
68
+
69
+ **For CI/CD (GitLab):**
70
+ - Add environment variables in GitLab: **Settings → CI/CD → Variables**
71
+ - Add each variable separately:
72
+ - `CODEMIE_API_URL`
73
+ - `CODEMIE_AUTH_URL`
74
+ - `CODEMIE_REALM`
75
+ - `CODEMIE_CLIENT_ID`
76
+ - `CODEMIE_CLIENT_SECRET` (mark as **Masked**)
77
+
78
+ ## Quick Start
79
+
80
+ ```bash
81
+ # Full validation with API connectivity check (default, recommended)
82
+ npm run validate
83
+
84
+ # Basic validation only (fast, no API connection)
85
+ npm run validate:basic
86
+
87
+ # Preview changes
88
+ npm run preview
89
+
90
+ # Deploy resources
91
+ npm run deploy
92
+
93
+ # Deploy resources and delete orphaned ones
94
+ npm run deploy -- --prune
95
+
96
+ # Remove all IaC-managed resources
97
+ npm run destroy
98
+
99
+ # Create backup of all resources
100
+ npm run backup
101
+
102
+ # Use external config file to override default names and locations for: codemie.yaml, .codemie/state.json, backups
103
+ npm run <command> --config codemie/iac.json
104
+ ```
105
+ **Note:** All commands work identically whether you use monolithic configuration or modular imports - the `$import` directives are automatically resolved during config loading.
106
+
107
+ **Config file structure:**
108
+ ```json
109
+ {
110
+ "rootDir": "root/of/working/directory",
111
+ "codemieConfig": "path/to/codemie.yaml",
112
+ "codemieState": "path/to/state.json",
113
+ "backupsDirectory": "path/to/backups"
114
+ }
115
+ ```
116
+ It is not mandatory to provide all fields - any missing fields will use default values.
117
+
118
+ **Default Config:**
119
+ ```json
120
+ {
121
+ "rootDir": ".",
122
+ "codemieConfig": "codemie.yaml",
123
+ "codemieState": ".codemie/state.json",
124
+ "backupsDirectory": "backups"
125
+ }
126
+ ```
127
+
128
+
129
+ **Validation types:**
130
+ - **Full validation** (`npm run validate`) checks:
131
+ - `codemie.yaml` syntax is valid
132
+ - All referenced files exist
133
+ - Required fields are present
134
+ - No cyclic dependencies in sub-assistants
135
+ - Assistants with sub-assistants cannot be sub-assistants themselves
136
+ - **Plus API checks:**
137
+ - Slug conflicts with existing assistants in Codemie (if slugs are provided)
138
+ - Ensures your slugs are globally unique before deployment
139
+
140
+ - **Basic validation** (`npm run validate:basic`) skips API checks (faster, no credentials needed)
141
+
142
+ ### CLI Usage
143
+
144
+ The tool provides a unified `codemie` command for all operations:
145
+
146
+ ```bash
147
+ # Show help and available commands
148
+ codemie --help
149
+
150
+ # Deploy resources
151
+ codemie deploy
152
+ codemie deploy --prune
153
+
154
+ # Other commands
155
+ codemie backup
156
+ codemie destroy --force
157
+ codemie preview
158
+ codemie validate --check-api
159
+ ```
160
+
161
+ **For local development**, npm scripts provide convenient shortcuts:
162
+ ```bash
163
+ npm run deploy # → codemie deploy
164
+ npm run backup # → codemie backup
165
+ npm run destroy # → codemie destroy --force
166
+ ```
167
+
168
+ ## 🔄 Migrating Existing Resources to IaC
169
+
170
+ If you already have assistants, datasources, and workflows created in Codemie UI, use the backup command to migrate them to IaC management:
171
+
172
+ ```bash
173
+ npm run backup
174
+ ```
175
+
176
+ ### What It Does
177
+
178
+ **Automated Export:**
179
+ - Fetches all resources from your Codemie platform (assistants, datasources, workflows, integrations)
180
+ - Generates IaC configuration files in `backups/YYYY-MM-DDTHH-MM-SS/` directory:
181
+ - `codemie.yaml` - Main configuration with all resources (MCP servers use integration aliasing)
182
+ - `state.json` - State file with resource IDs and checksums
183
+ - `system_prompts/*.prompt.md` - Assistant system prompts
184
+ - `workflows/*.yaml` - Workflow definitions
185
+ - `openapi_specs/*.json` - OpenAPI tool specifications
186
+
187
+ **Transaction Safety:**
188
+ - Atomic backup process with rollback on failure
189
+ - Resume capability - if backup is interrupted, rerunning continues from last checkpoint
190
+ - Temporary directory used during backup (`.temp-*`) - moved to final location only on success
191
+ - Progress tracking with `transaction.json` checkpoint file
192
+
193
+ **Type-Safe Conversions:**
194
+ - SDK response types → IaC resource formats with proper field mapping
195
+ - Workflow YAML includes assistant ID → name resolution for readability
196
+
197
+ ### Migration Workflow
198
+
199
+ **Step 1: Create Backup**
200
+ ```bash
201
+ npm run backup
202
+ ```
203
+
204
+ Output:
205
+ ```
206
+ 🗄️ Creating backup of all Codemie resources...
207
+
208
+ 🔌 Connecting to Codemie API...
209
+ ✓ Connected to Codemie API
210
+
211
+ 📁 Temporary backup directory: backups/.temp-2025-01-27
212
+
213
+ 🤖 Fetching assistants...
214
+ Found 15 assistant(s)
215
+ • TAD BA Helper (ast-123)
216
+ • TAD Code Analyst (ast-456)
217
+ ...
218
+ ✓ Backed up 15 assistant(s)
219
+
220
+ 📊 Fetching datasources...
221
+ Found 8 datasource(s)
222
+ ✓ Backed up 8 datasource(s)
223
+
224
+ 🔄 Fetching workflows...
225
+ Found 3 workflow(s)
226
+ ✓ Backed up 3 workflow(s)
227
+
228
+ 🔄 Finalizing backup...
229
+ ✓ Backup finalized at backups/2025-01-27T14-30-45
230
+
231
+ ==================================================
232
+ 📊 Backup Summary:
233
+
234
+ 🤖 Assistants: 15
235
+ 📊 Datasources: 8
236
+ 🔄 Workflows: 3
237
+ 🔌 Integrations: 5
238
+
239
+ 📁 Location: backups/2025-01-27T14-30-45
240
+ ```
241
+
242
+ **Step 2: Review Generated Files**
243
+
244
+ ```bash
245
+ cd backups/2025-01-27T14-30-45
246
+ ls -la
247
+ ```
248
+
249
+ Files created:
250
+ ```
251
+ codemie.yaml # Main IaC configuration
252
+ state.json # Resource state (IDs, checksums)
253
+ system_prompts/ # Assistant system prompts
254
+ tad-ba-helper.prompt.md
255
+ tad-code-analyst.prompt.md
256
+ workflows/ # Workflow definitions
257
+ code-review-workflow.yaml
258
+ openapi_specs/ # OpenAPI tool specs
259
+ ```
260
+
261
+ **Step 3: Copy to Your IaC Project**
262
+
263
+ ```bash
264
+ # Option A: Replace entire configuration
265
+ cp backups/2025-01-27T14-30-45/* ./
266
+ mv backups/2025-01-27T14-30-45/system_prompts/* system_prompts/
267
+ mv backups/2025-01-27T14-30-45/workflows/* workflows/
268
+ mv backups/2025-01-27T14-30-45/openapi_specs/* openapi_specs/
269
+
270
+ # Option B: Merge specific resources into existing config
271
+ # Manually copy needed sections from backups/2025-01-27T14-30-45/codemie.yaml
272
+ ```
273
+
274
+ **Step 4: Validate & Deploy**
275
+
276
+ ```bash
277
+ npm run validate # Check configuration
278
+ npm run preview # Preview (should show "No changes")
279
+ npm run deploy # Deploy (updates state file with current checksums)
280
+ ```
281
+
282
+ ### Troubleshooting
283
+
284
+ **Backup Interrupted?**
285
+ - Just run `npm run backup` again - it will resume from last checkpoint
286
+ - Transaction file (`transaction.json`) tracks progress
287
+ - Temporary directory (`.temp-*`) will be cleaned up automatically
288
+
289
+ **Backup Failed Completely?**
290
+ - Check `.temp-*` directory exists - if yes, partial backup was attempted
291
+ - Error message will indicate which resource failed
292
+ - Temporary directory will be automatically cleaned up (rollback)
293
+ - Fix the issue and rerun backup
294
+
295
+ **Code Datasource Missing Repository Link?**
296
+ - Some code datasources may show warning: `⚠️ Code datasource missing repository link`
297
+ - SDK sometimes doesn't return `code.link` field
298
+ - Manually add `link: https://github.com/...` in `codemie.yaml` datasource section
299
+
300
+ **Workflow Assistant IDs Not Resolved?**
301
+ - If workflow YAML contains `assistant_id: ast-xxx` instead of assistant name
302
+ - This happens when assistant doesn't exist in backup (e.g., deleted or from another project)
303
+ - Manually replace with correct assistant name or ID in workflow YAML file
304
+
305
+ **Resume From Specific Point?**
306
+ - Transaction file tracks what's completed: `transaction.json`
307
+ - Contains: `completed: ['ast-1', 'ast-2']` and `failed: [{id: 'ast-3', error: '...'}]`
308
+ - To force fresh backup: delete `backups/YYYY-MM-DDTHH-MM-SS/transaction.json` before rerunning
309
+
310
+ ## 📝 Prompt Compilation System
311
+
312
+ The repository includes an **automated prompt compilation system** for managing complex prompts with reusable components and configuration.
313
+
314
+ ### When to Use Compilation
315
+
316
+ **Use template-based compilation for:**
317
+ - Prompts with shared components (includes)
318
+ - Multiple configuration variants
319
+ - Team collaboration on modular components
320
+ - Complex prompts that benefit from DRY principles
321
+
322
+ **Use direct editing for:**
323
+ - Simple, self-contained prompts
324
+ - Quick changes or updates
325
+ - Prompts that don't need shared components
326
+
327
+ ### Quick Start
328
+
329
+ ```bash
330
+ # Compile specific agent
331
+ npm run compile -- --prompt tad-ba-helper
332
+
333
+ # Compile all prompts
334
+ npm run compile:all
335
+
336
+ # Check if compiled files are up-to-date
337
+ npm run compile:check
338
+
339
+ # Verbose output
340
+ npm run compile:all -- --verbose
341
+ ```
342
+
343
+ > **Note:** Compilation functionality is available only as internal npm scripts. The compile command is not exposed in the published `codemie-iac` package, which focuses exclusively on infrastructure management (deploy, validate, preview, destroy, backup).
344
+
345
+ ### Directory Structure
346
+
347
+ ```
348
+ prompt_source/ # Source templates
349
+ ├── shared/ # Shared includes
350
+ │ ├── jira-processing.include.md
351
+ │ └── confluence-processing.include.md
352
+ └── {agent-name}/ # Agent directory
353
+ ├── {agent}.prompt.md # Template with placeholders
354
+ ├── {agent}.config.yaml # Configuration values
355
+ └── {agent}.requirements.md # Requirements doc
356
+
357
+ system_prompts/ # Ready-to-deploy prompts
358
+ ├── README.md # Documentation
359
+ └── *.prompt.md # Final prompts (some auto-compiled)
360
+ ```
361
+
362
+ ### Placeholder Types
363
+
364
+ The compilation system handles three types of placeholders:
365
+
366
+ 1. **Config Placeholders** - `{config.key}`
367
+ - Resolved during compilation from `.config.yaml`
368
+ - Example: `{team_ids.prescreening}` → `91267`
369
+
370
+ 2. **Runtime Variables** - `{{system}}`
371
+ - Preserved for Codemie platform (resolved at runtime)
372
+ - Example: `{{current_user}}`, `{{date}}`
373
+
374
+ 3. **Documentation Examples** - `<example>`
375
+ - Part of prompt text, never resolved
376
+ - Example: `<param_name>`, `<user_id>`
377
+
378
+ ### Example Template
379
+
380
+ **Source:** `prompt_source/my-agent/my-agent.prompt.md`
381
+ ```markdown
382
+ ---
383
+ prompt_name: My Agent
384
+ prompt_version: 1.0.0
385
+ ---
386
+
387
+ # Instructions
388
+
389
+ {include:jira-processing}
390
+
391
+ Use team ID: {team_ids.my_team}
392
+ Current user: {{current_user}}
393
+ ```
394
+
395
+ **Config:** `prompt_source/my-agent/my-agent.config.yaml`
396
+ ```yaml
397
+ prompt_version: 1.0.0
398
+
399
+ team_ids:
400
+ my_team: "12345"
401
+ ```
402
+
403
+ **Compiled:** `system_prompts/my-agent/my-agent.prompt.md`
404
+ ```markdown
405
+ ---
406
+ prompt_name: My Agent
407
+ prompt_version: 1.0.0
408
+ ---
409
+
410
+ # Instructions
411
+
412
+ [Full content of jira-processing.include.md inserted here]
413
+
414
+ Use team ID: 12345
415
+ Current user: {{current_user}}
416
+ ```
417
+
418
+ ### CI/CD Integration
419
+
420
+ Compilation is **fully automated** in the deployment pipeline:
421
+
422
+ 1. **Compile Stage** - Runs before validation
423
+ 2. **Validation** - Checks for unresolved placeholders
424
+ 3. **Deployment** - Deploys compiled prompts
425
+ 4. **Auto-Commit** - CI commits compiled files back to repository
426
+
427
+ **Workflow:**
428
+ - Edit source files in `prompt_source/`
429
+ - Push to repository
430
+ - CI automatically compiles and deploys
431
+ - Compiled files updated in `system_prompts/`
432
+
433
+ ### Extensible Architecture
434
+
435
+ The compilation system uses a **plugin-based architecture** for easy extension:
436
+
437
+ - **ProcessorPlugin** - Custom content transformations
438
+ - **ValidatorPlugin** - Custom validation rules
439
+ - **Type-safe** - Full TypeScript support
440
+ - **Well-documented** - See `ARCHITECTURE.md` for details
441
+
442
+ For complete documentation:
443
+ - **Source Templates**: `prompt_source/README.md`
444
+ - **System Prompts**: `system_prompts/README.md`
445
+ - **Architecture**: `ARCHITECTURE.md`
446
+ - **Development Guide**: `CONTRIBUTING.md`
447
+
448
+ ## Configuration Structure
449
+
450
+ All resources are defined in `codemie.yaml`:
451
+
452
+ ```yaml
453
+ version: 1
454
+
455
+ project:
456
+ name: ta-desk
457
+ description: Your project description
458
+
459
+ environment:
460
+ codemie_api_url: ${CODEMIE_API_URL}
461
+ # ... other env vars
462
+
463
+ imported:
464
+ integrations: # Platform integrations (referenced via $ref)
465
+ assistants: # Existing assistants (for workflows)
466
+ datasources: # Existing datasources
467
+
468
+ resources:
469
+ datasources: # Datasources to create/manage
470
+ assistants: # Assistants to create/manage
471
+ workflows: # Workflows to create/manage
472
+ ```
473
+
474
+ For detailed examples of each resource type, see:
475
+ - `examples/datasource-examples.yaml` - All datasource types with field descriptions
476
+ - `examples/assistant-examples.yaml` - Assistant patterns and configurations
477
+ - `examples/toolkit-examples.yaml` - All toolkit configurations
478
+ - `examples/workflow-examples.yaml` - Workflow patterns and structures
479
+
480
+ ## 📁 Configuration Organization
481
+
482
+ ### Modular Configuration with `$import`
483
+
484
+ For large projects, you can split configuration into multiple files using the `$import` directive. The ConfigLoader automatically resolves imports and supports three organization styles:
485
+
486
+ #### Style 1: Monolithic
487
+
488
+ Keep everything in one file - perfect for small projects:
489
+
490
+ ```yaml
491
+ # codemie.yaml
492
+ version: 1
493
+ project:
494
+ name: my-project
495
+
496
+ resources:
497
+ datasources:
498
+ - name: repo-1
499
+ type: code
500
+ link: https://github.com/org/repo-1
501
+ - name: repo-2
502
+ type: code
503
+ link: https://github.com/org/repo-2
504
+
505
+ assistants:
506
+ - name: Assistant 1
507
+ prompt: ./system_prompts/assistant-1.prompt.md
508
+ model: gpt-4o
509
+ ```
510
+
511
+ #### Style 2: Grouped Resources
512
+
513
+ Group related resources in array files:
514
+
515
+ ```yaml
516
+ # codemie.yaml
517
+ resources:
518
+ datasources:
519
+ - $import: configs/datasources/all-repos.yaml
520
+ - $import: configs/datasources/knowledge-bases.yaml
521
+
522
+ assistants:
523
+ - $import: configs/assistants/ba-team.yaml
524
+ - $import: configs/assistants/dev-team.yaml
525
+ ```
526
+
527
+ ```yaml
528
+ # configs/datasources/all-repos.yaml
529
+ - name: repo-1
530
+ type: code
531
+ link: https://github.com/org/repo-1
532
+
533
+ - name: repo-2
534
+ type: code
535
+ link: https://github.com/org/repo-2
536
+
537
+ - name: repo-3
538
+ type: code
539
+ link: https://github.com/org/repo-3
540
+ ```
541
+
542
+ ```yaml
543
+ # configs/assistants/ba-team.yaml
544
+ - name: BA Reviewer
545
+ prompt: ./system_prompts/ba-reviewer.prompt.md
546
+ model: claude-3-7
547
+
548
+ - name: BA Helper
549
+ prompt: ./system_prompts/ba-helper.prompt.md
550
+ model: gpt-4.1
551
+ sub_assistants:
552
+ - BA Reviewer
553
+ ```
554
+
555
+ #### Style 3: Individual Files
556
+
557
+ Each resource in a separate file for maximum modularity:
558
+
559
+ ```yaml
560
+ # codemie.yaml
561
+ resources:
562
+ datasources:
563
+ - $import: configs/datasources/repo-1.yaml
564
+ - $import: configs/datasources/repo-2.yaml
565
+ - $import: configs/datasources/jira-kb.yaml
566
+
567
+ assistants:
568
+ - $import: configs/assistants/ba-reviewer.yaml
569
+ - $import: configs/assistants/ba-helper.yaml
570
+ - $import: configs/assistants/code-reviewer.yaml
571
+ ```
572
+
573
+ ```yaml
574
+ # configs/datasources/repo-1.yaml
575
+ name: repo-1
576
+ type: code
577
+ description: Repository 1
578
+ link: https://github.com/org/repo-1
579
+ branch: main
580
+ ```
581
+
582
+ ```yaml
583
+ # configs/assistants/ba-reviewer.yaml
584
+ name: BA Reviewer
585
+ description: Reviews BA artifacts
586
+ prompt: ./system_prompts/ba-reviewer.prompt.md
587
+ model: claude-3-7
588
+ shared: true
589
+ toolkits:
590
+ - toolkit: Project Management
591
+ tools:
592
+ - $ref: tool_definitions.jira_tool
593
+ ```
594
+
595
+ #### Style 4: Hybrid
596
+
597
+ Mix all approaches based on your needs:
598
+
599
+ ```yaml
600
+ # codemie.yaml
601
+ resources:
602
+ datasources:
603
+ # Inline for quick tests
604
+ - name: test-repo
605
+ type: code
606
+ link: https://github.com/org/test
607
+
608
+ # Array import for simple repos
609
+ - $import: configs/datasources/simple-repos.yaml
610
+
611
+ # Individual files for critical resources
612
+ - $import: configs/datasources/production-jira.yaml
613
+ - $import: configs/datasources/production-confluence.yaml
614
+
615
+ assistants:
616
+ # Team groups
617
+ - $import: configs/assistants/ba-team.yaml
618
+ - $import: configs/assistants/dev-team.yaml
619
+
620
+ # VIP assistants separately
621
+ - $import: configs/assistants/ceo-assistant.yaml
622
+ ```
623
+
624
+ ### Import Features
625
+
626
+ **Object Imports:**
627
+ ```yaml
628
+ # Import entire sections
629
+ tool_definitions:
630
+ $import: configs/shared/tool-definitions.yaml
631
+
632
+ datasource_defaults:
633
+ $import: configs/shared/datasource-defaults.yaml
634
+ ```
635
+
636
+ **Circular Import Protection:**
637
+ - Automatically detects circular dependencies (file-a → file-b → file-a)
638
+ - Throws clear error with import chain: `Circular import detected: [file-a.yaml, file-b.yaml, file-a.yaml]`
639
+ - Allows same file in different branches (tree structure, not linear chain)
640
+
641
+ **Nested Imports:**
642
+ ```yaml
643
+ # configs/datasources/all-repos.yaml
644
+ - $import: base-repos.yaml # Import from same directory
645
+ - name: additional-repo
646
+ type: code
647
+ link: https://github.com/org/additional
648
+ ```
649
+
650
+ **Cross-Project Reuse:**
651
+ ```yaml
652
+ # Project A
653
+ resources:
654
+ assistants:
655
+ - $import: ../shared-assistants/code-reviewer.yaml
656
+ - $import: configs/assistants/project-a-specific.yaml
657
+
658
+ # Project B
659
+ resources:
660
+ assistants:
661
+ - $import: ../shared-assistants/code-reviewer.yaml
662
+ - $import: configs/assistants/project-b-specific.yaml
663
+ ```
664
+
665
+ ### Recommended Structure
666
+
667
+ ```
668
+ project-root/
669
+ ├── codemie.yaml # Main config (imports only)
670
+ ├── configs/
671
+ │ ├── project.yaml # Project metadata
672
+ │ ├── environment.yaml # Environment variables
673
+ │ ├── imported.yaml # Imported resources
674
+ │ ├── shared/
675
+ │ │ ├── tool-definitions.yaml
676
+ │ │ └── datasource-defaults.yaml
677
+ │ ├── datasources/
678
+ │ │ ├── repos/
679
+ │ │ │ ├── frontend-repos.yaml
680
+ │ │ │ └── backend-repos.yaml
681
+ │ │ └── knowledge-bases/
682
+ │ │ ├── jira-production.yaml
683
+ │ │ └── confluence-production.yaml
684
+ │ ├── assistants/
685
+ │ │ ├── ba-team/
686
+ │ │ │ ├── ba-reviewer.yaml
687
+ │ │ │ └── ba-helper.yaml
688
+ │ │ └── dev-team/
689
+ │ │ ├── code-reviewer.yaml
690
+ │ │ └── codebase-digger.yaml
691
+ │ └── workflows/
692
+ │ ├── test-automation.yaml
693
+ │ └── release-notes.yaml
694
+ ├── system_prompts/
695
+ │ └── *.prompt.md
696
+ └── workflows/
697
+ └── *.yaml
698
+ ```
699
+
700
+ ## 📁 File Structure
701
+
702
+ ```
703
+ assistant-resources/
704
+ ├── codemie.yaml # Main IaC configuration
705
+ ├── .codemie/
706
+ │ └── state.json # Deployment state (committed to Git)
707
+ ├── system_prompts/
708
+ │ └── *.prompt.md # Prompt content files
709
+ ├── workflows/
710
+ │ └── *.yaml # Workflow definitions
711
+ ├── examples/ # Configuration examples (reference)
712
+ │ ├── datasource-examples.yaml
713
+ │ ├── assistant-examples.yaml
714
+ │ ├── toolkit-examples.yaml
715
+ │ └── workflow-examples.yaml
716
+ └── src/ # IaC implementation
717
+ ```
718
+
719
+ ## Key Features
720
+
721
+ ### Modular Configuration with `$import`
722
+
723
+ Organize your configuration across multiple files for better maintainability and team collaboration. The `$import` directive automatically resolves imports during config loading:
724
+
725
+ ```yaml
726
+ # Main config - clean and organized
727
+ resources:
728
+ datasources:
729
+ - $import: configs/datasources/repo-1.yaml # Single resource
730
+ - $import: configs/datasources/all-repos.yaml # Array of resources
731
+
732
+ assistants:
733
+ - $import: configs/assistants/ba-team.yaml
734
+ ```
735
+
736
+ Supports inline resources, individual files, array files, and any combination. See [Configuration Organization](#-configuration-organization) for details.
737
+
738
+ ### Name-Based Resource Management
739
+
740
+ Resources are identified by their `name` field. Renaming a resource in `codemie.yaml` results in deleting the old resource and creating a new one.
741
+
742
+ **Why names instead of IDs?**
743
+ 1. **Platform generates UUIDs** - You don't know the ID until after creation, making it impossible to write config before deployment
744
+ 2. **Git-friendly** - Human-readable names enable meaningful diffs in pull requests: "Added Customer Support Bot" vs "Added resource a3f2b8c9-..."
745
+ 3. **Team collaboration** - Names are self-documenting; team members understand what changed without looking up UUIDs
746
+ 4. **Config portability** - Same config can be deployed to different environments without ID conflicts
747
+
748
+ **Why delete+create on rename?**
749
+ - Without UUIDs in config, there's no way to track that "Old Name" became "New Name"
750
+ - Alternative would require manual migration steps, defeating IaC purpose
751
+ - State file (`state.json`) maps names→UUIDs for updates, but rename breaks this mapping
752
+
753
+ **About slugs:**
754
+ - `slug` is **optional** for all assistants
755
+ - Platform auto-generates slug from name if not provided
756
+ - **Recommendation:** Don't specify slug unless you have specific requirements
757
+ - Sub-assistants use **names** (not slugs)
758
+ - Workflows reference assistants by **name**
759
+
760
+ ### Checksum-Based Change Detection
761
+
762
+ Changes to prompts and configuration are detected via SHA256 checksums, ensuring only modified resources are updated.
763
+
764
+ **Why checksums instead of timestamps or full comparison?**
765
+ 1. **Idempotency** - Same config produces same checksums, enabling safe re-runs without unintended changes
766
+ 2. **Efficiency** - Avoid costly API calls to fetch resources for comparison when nothing changed
767
+ 3. **Precision** - Separate checksums for prompt content and resource config allow granular change detection
768
+ 4. **Git integration** - Checksums stored in `state.json` provide audit trail of what was actually deployed
769
+
770
+ **How it works:**
771
+ - Prompt checksum: SHA256 of prompt file content
772
+ - Config checksum: SHA256 of resource configuration (excluding prompt path, including all other fields)
773
+ - On deployment: Compare stored checksums with current checksums
774
+ - Only update if either checksum differs
775
+
776
+ ### Orphaned Resource Cleanup
777
+
778
+ Resources removed from `codemie.yaml` are NOT automatically deleted by default. To remove them, you must explicitly use the `--prune` flag.
779
+
780
+ **How orphaned resources are detected:**
781
+ 1. Load `state.json` - contains all resources created by IaC with their names and UUIDs
782
+ 2. Load `codemie.yaml` - contains desired state (what should exist)
783
+ 3. Compare: For each resource in `state.json`, check if it exists in `codemie.yaml`
784
+ 4. If resource is in state but NOT in config → mark as orphaned
785
+ 5. If `--prune` is used: Delete orphaned resources from platform using their UUID
786
+ 6. Remove from `state.json`
787
+
788
+ **Safety mechanisms:**
789
+ - **Opt-in cleanup** - `npm run deploy` never deletes resources unless you pass `--prune`.
790
+ - **Only IaC-created resources** - Resources NOT in `state.json` are never deleted (manually created resources are safe)
791
+ - **Per-resource-type** - Checks assistants, datasources, workflows separately
792
+ - **Logged deletion** - Each deletion is logged with resource name and UUID for audit
793
+
794
+ **Why automatic cleanup?**
795
+ - **GitOps principle** - Config is source of truth; platform state should match config
796
+ - **No manual cleanup** - Prevents orphaned resources accumulating over time
797
+ - **Safe refactoring** - Rename/restructure resources without leaving behind old versions
798
+
799
+ ### Workflow Assistant Resolution
800
+
801
+ Workflows reference assistants by `assistant_name`, which are resolved to platform UUIDs during deployment from `state.json` or `imported.assistants`.
802
+
803
+ **Why name-based references in workflows?**
804
+ 1. **Readability** - `assistant_name: "Code Reviewer"` vs `assistant_id: "a3f2b8c9-..."`
805
+ 2. **Maintainability** - Update assistant name in one place (codemie.yaml), workflows auto-resolve
806
+ 3. **Versionability** - Git diffs show meaningful changes: "Changed to Data Analyzer" vs changed UUID
807
+ 4. **Cross-environment** - Same workflow YAML works in dev/prod with different assistant UUIDs
808
+
809
+ **Resolution order:**
810
+ 1. Check `state.json` - IaC-created assistants (have name→UUID mapping)
811
+ 2. Check `imported.assistants` - Pre-existing platform assistants referenced by config
812
+ 3. If not found → deployment fails with clear error message
813
+
814
+ This happens during `npm run deploy`, before sending workflow YAML to API.
815
+
816
+ ### Integration Aliasing with `$ref`
817
+
818
+ Avoid duplication by referencing integrations:
819
+
820
+ ```yaml
821
+ imported:
822
+ integrations:
823
+ - alias: jira_connection
824
+ id: 9ab1ad26-07f1-4d1a-9b0b-33d33a9d2cde
825
+ credential_type: Jira
826
+
827
+ resources:
828
+ # For datasources: use .id suffix to get UUID string
829
+ datasources:
830
+ - name: my-jira-kb
831
+ type: knowledge_base_jira
832
+ setting_id: $ref:imported.integrations.jira_connection.id # → "9ab1ad26..."
833
+ jql: project = MY
834
+
835
+ # For toolkits: reference full object (no .id suffix)
836
+ assistants:
837
+ - name: My Assistant
838
+ toolkits:
839
+ - toolkit: Project Management
840
+ tools:
841
+ - name: generic_jira_tool
842
+ settings:
843
+ $ref: imported.integrations.jira_connection # → full object
844
+ ```
845
+
846
+ **Why `$ref` instead of repeating integration IDs?**
847
+ 1. **Single source of truth** - Integration ID defined once, used everywhere
848
+ 2. **Easier updates** - Change integration ID in one place, applies to all references
849
+ 3. **Reduced errors** - Copy-paste mistakes eliminated
850
+ 4. **Semantic clarity** - `$ref:imported.integrations.jira_connection.id` explains what it references
851
+
852
+ **How `$ref` works:**
853
+ - **For datasources**: Path MUST end with `.id` to get the UUID string
854
+ - `$ref:imported.integrations.name.id` → resolves to UUID string
855
+ - **For toolkits**: Path references the full object (no `.id` suffix)
856
+ - `$ref:imported.integrations.name` → resolves to full integration object
857
+ - During config load, `ConfigLoader` resolves all `$ref` references
858
+ - Validation ensures referenced path exists before deployment
859
+
860
+ ## State Management
861
+
862
+ The `.codemie/state.json` file tracks IaC-created resources:
863
+
864
+ ```json
865
+ {
866
+ "version": "1",
867
+ "project": "ta-desk",
868
+ "lastSync": "2025-01-15T10:30:00Z",
869
+ "resources": {
870
+ "assistants": {
871
+ "My Assistant": {
872
+ "id": "uuid-here",
873
+ "promptChecksum": "sha256-hash",
874
+ "configChecksum": "sha256-hash"
875
+ }
876
+ },
877
+ "datasources": { ... },
878
+ "workflows": { ... }
879
+ }
880
+ }
881
+ ```
882
+
883
+ **Why commit state.json to Git?**
884
+ 1. **CI/CD requirement** - Pipeline needs to know what's deployed to calculate changes
885
+ 2. **Team visibility** - Everyone sees current production state
886
+ 3. **Audit trail** - Git history shows who deployed what and when
887
+ 4. **No external backend** - Simpler than S3/Consul/etc.; Git is the backend
888
+
889
+ **Why no state locking?**
890
+ - GitLab CI/CD `resource_group: production` ensures sequential execution
891
+ - Only one pipeline runs at a time → no concurrent modifications → no race conditions
892
+ - State conflicts impossible with proper CI/CD setup
893
+
894
+ ## 📝 Configuration Guide
895
+
896
+ ### Importing Existing Resources from Platform
897
+
898
+ When you want to reference resources that already exist on the Codemie platform (created manually or by another team), you need to import them into your IaC configuration.
899
+
900
+ #### Why Import Resources?
901
+
902
+ **For Integrations:**
903
+ - Integrations are created in Codemie UI
904
+ - IaC only references them - doesn't create or manage them
905
+ - Required for datasources and toolkits to authenticate
906
+
907
+ **For Datasources:**
908
+ - Reuse datasources created by other teams
909
+ - Avoid duplicate indexing of the same data
910
+ - Share knowledge bases across multiple assistants
911
+
912
+ **For Assistants:**
913
+ - Reference existing assistants in workflows
914
+ - Use assistants as sub-assistants without managing them
915
+ - Collaborate across teams without duplicating resources
916
+
917
+ #### How to Import Resources
918
+
919
+ **Step 1: Find the resource in Codemie UI**
920
+
921
+ For **Integrations**:
922
+ 1. Go to Codemie UI → Integrations
923
+ 2. Find your integration (e.g., "Git Server Connection")
924
+ 3. Copy the UUID from the URL or integration details
925
+ 4. Note the integration type (Git, Jira, Confluence, etc.)
926
+
927
+ For **Datasources**:
928
+ 1. Go to Codemie UI → Data Sources
929
+ 2. Find your datasource
930
+ 3. Copy the UUID from the URL (e.g., `8994c477-fc97-4fc0-a1e6-b73be514f684`)
931
+ 4. Note the datasource name and type
932
+
933
+ For **Assistants**:
934
+ 1. Go to Codemie UI → Assistants
935
+ 2. Find your assistant
936
+ 3. Copy the UUID from the URL (e.g., `79db7d36-eb89-468d-a99f-44fd4bf92b01`)
937
+ 4. Note the exact assistant name
938
+
939
+ **Step 2: Add to `imported` section in codemie.yaml**
940
+
941
+ ```yaml
942
+ imported:
943
+ # Integrations (created in Codemie UI, referenced by datasources/toolkits)
944
+ integrations:
945
+ - alias: git_server_connection
946
+ id: f1e53ba4-5ab1-4c05-ad8f-c3625ba5a155 # From Codemie UI
947
+ credential_type: Git
948
+
949
+ - alias: jira_connection
950
+ id: 9ab1ad26-07f1-4d1a-9b0b-33d33a9d2cde
951
+ credential_type: Jira
952
+
953
+ - alias: confluence_connection
954
+ id: d0f8c5aa-afbb-45a6-9fa3-a2a39ac7e0cb
955
+ credential_type: Confluence
956
+
957
+ # Datasources (existing datasources to reuse)
958
+ datasources:
959
+ - id: 8994c477-fc97-4fc0-a1e6-b73be514f684 # From Codemie UI
960
+ name: Confluence-6May2025 # Exact name from platform
961
+ type: knowledge_base_confluence
962
+
963
+ - id: b31ac927-37ec-4038-bdcc-98fab5d76ec1
964
+ name: Jira-Production-KB
965
+ type: knowledge_base_jira
966
+
967
+ # Assistants (existing assistants to reference in workflows/sub-assistants)
968
+ assistants:
969
+ - id: 79db7d36-eb89-468d-a99f-44fd4bf92b01 # From Codemie UI
970
+ name: TA Desk Front-End Code Reviewer # Exact name from platform
971
+
972
+ - id: 96e2d32a-1fe3-483c-b444-4afec9134928
973
+ name: Checklist Generator Assistant
974
+ ```
975
+
976
+ **Step 3: Use imported resources in your configuration**
977
+
978
+ ```yaml
979
+ resources:
980
+ datasources:
981
+ # Use imported integration
982
+ - name: my-repo
983
+ type: code
984
+ link: https://git.example.com/repo
985
+ branch: master
986
+ setting_id: $ref:imported.integrations.git_server_connection.id # Reference
987
+
988
+ assistants:
989
+ # Use imported datasource
990
+ - name: My Assistant
991
+ prompt: ./system_prompts/assistant.prompt.md
992
+ model: gpt-4o
993
+ context:
994
+ - context_type: knowledge_base
995
+ name: Confluence-6May2025 # References imported datasource
996
+
997
+ # Use imported integration in toolkit
998
+ toolkits:
999
+ - toolkit: Project Management
1000
+ tools:
1001
+ - name: generic_jira_tool
1002
+ label: Generic Jira
1003
+ settings_config: false
1004
+ settings:
1005
+ $ref: imported.integrations.jira_connection # Reference
1006
+
1007
+ # Use imported assistant as sub-assistant
1008
+ sub_assistants:
1009
+ - TA Desk Front-End Code Reviewer # References imported assistant
1010
+
1011
+ workflows:
1012
+ - name: My Workflow
1013
+ definition: ./workflows/workflow.yaml
1014
+ mode: Sequential
1015
+ ```
1016
+
1017
+ **Important Notes:**
1018
+
1019
+ - **Integration IDs**: Find in Codemie UI → Integrations (usually in URL or settings)
1020
+ - **Datasource IDs**: Find in Codemie UI → Data Sources → Select datasource → Check URL
1021
+ - **Assistant IDs**: Find in Codemie UI → Assistants → Select assistant → Check URL
1022
+ - **Exact names**: Must match platform names exactly (case-sensitive)
1023
+ - **Type validation**: IaC validates that types match platform resources
1024
+ - **Access permissions**: Service account must have access to imported resources
1025
+
1026
+ **Why use `imported` instead of creating via IaC?**
1027
+
1028
+ | Resource Type | When to Import | When to Create via IaC |
1029
+ |---------------|----------------|------------------------|
1030
+ | **Integrations** | Always (created in UI only) | Not yet supported |
1031
+ | **Datasources** | Shared across teams, large/expensive to index | Team-specific datasources |
1032
+ | **Assistants** | Managed by other teams, stable production assistants | Your team's assistants |
1033
+
1034
+ ### Nested Assistants (Sub-Assistants)
1035
+
1036
+ You can link assistants together using `sub_assistants` (name-based):
1037
+
1038
+ ```yaml
1039
+ resources:
1040
+ assistants:
1041
+ # Sub-assistant (must be defined first)
1042
+ - name: Sub Assistant Helper
1043
+ prompt: ./system_prompts/sub.prompt.md
1044
+ description: "Helper assistant"
1045
+ model: gpt-4o
1046
+
1047
+ # Main assistant with nested sub-assistant
1048
+ - name: Main Assistant
1049
+ prompt: ./system_prompts/main.prompt.md
1050
+ description: "Main assistant with helper"
1051
+ model: gpt-4o
1052
+ sub_assistants:
1053
+ - "Sub Assistant Helper" # Reference by NAME
1054
+ ```
1055
+
1056
+ **How it works:**
1057
+ - Define sub-assistants **before** the main assistant in the YAML
1058
+ - Use `sub_assistants` to reference them by **name** (name-based approach)
1059
+ - During deployment, names are automatically resolved to IDs from `state.json`
1060
+ - Sub-assistants must exist (be deployed first) for resolution to work
1061
+
1062
+ **⚠️ Important restrictions:**
1063
+ - **No cyclic dependencies:** A → B → C → A is not allowed
1064
+ - **No nested sub-assistants:** If an assistant has `sub_assistants`, it cannot be used as a sub-assistant by another assistant
1065
+ - Example of **invalid** configuration:
1066
+ ```yaml
1067
+ # ❌ Invalid: Middle has sub-assistants AND is used as sub-assistant
1068
+ assistants:
1069
+ - name: Helper
1070
+ model: gpt-4o
1071
+
1072
+ - name: Middle
1073
+ model: gpt-4o
1074
+ sub_assistants: ["Helper"] # Middle has sub-assistants
1075
+
1076
+ - name: Main
1077
+ model: gpt-4o
1078
+ sub_assistants: ["Middle"] # ❌ Middle cannot be sub-assistant!
1079
+ ```
1080
+
1081
+ **📋 Deployment Order:**
1082
+
1083
+ IaC automatically handles deployment order to resolve dependencies:
1084
+
1085
+ 1. **Datasources first** - All datasources are created before assistants
1086
+ 2. **Sub-assistants before main** - Assistants are deployed in definition order
1087
+ 3. **Assistants before workflows** - Workflows are deployed last
1088
+
1089
+ **💡 Best Practice:** Define resources in the order they're referenced (datasources → sub-assistants → main assistants → workflows) for clarity.
1090
+
1091
+ ### Toolkits for Assistants
1092
+
1093
+ Toolkits provide additional capabilities to assistants, such as Git operations, Project Management (Jira/Confluence), and OpenAPI integration.
1094
+
1095
+ > **🔧 For detailed examples**, see `examples/toolkit-examples.yaml` with all available toolkits and their configurations.
1096
+
1097
+ **Available Toolkits:**
1098
+ 1. **Git** - Git operations (PR changes, diffs)
1099
+ 2. **Project Management** - Jira and Confluence integration
1100
+ 3. **OpenAPI** - OpenAPI specification tools
1101
+
1102
+ **Available MCP Integrations:**
1103
+ 1. **Figma MCP** - Figma design tool integration
1104
+ 2. **Atlassian MCP** - Alternative Jira/Confluence integration (more advanced than toolkit)
1105
+ 3. **Custom MCP** - Any MCP-compatible server
1106
+
1107
+ #### Integration Aliases & Tool Definitions
1108
+
1109
+ To avoid repeating integration and tool settings across multiple assistants, you can define them once and reference using aliases:
1110
+
1111
+ **Two-Level System:**
1112
+
1113
+ ```yaml
1114
+ # Level 1: Define integrations (created in Codemie UI)
1115
+ imported:
1116
+ integrations:
1117
+ - alias: jira_main
1118
+ id: "9ab1ad26-07f1-4d1a-9b0b-33d33a9d2cde"
1119
+ credential_type: Jira
1120
+
1121
+ - alias: confluence_main
1122
+ id: "d0f8c5aa-afbb-45a6-9fa3-a2a39ac7e0cb"
1123
+ credential_type: Confluence
1124
+
1125
+ # Level 2: Define tools (referencing integrations)
1126
+ tool_definitions:
1127
+ jira_tool:
1128
+ name: generic_jira_tool
1129
+ label: Generic Jira
1130
+ settings_config: false
1131
+ settings:
1132
+ $ref: imported.integrations.jira_main # References integration
1133
+
1134
+ confluence_tool:
1135
+ name: generic_confluence_tool
1136
+ label: Generic Confluence
1137
+ settings_config: false
1138
+ settings:
1139
+ $ref: imported.integrations.confluence_main
1140
+
1141
+ # Level 3: Use tools in assistants
1142
+ resources:
1143
+ assistants:
1144
+ - name: BA Assistant
1145
+ model: gpt-4o
1146
+ toolkits:
1147
+ - toolkit: Project Management
1148
+ tools:
1149
+ - $ref: tool_definitions.jira_tool
1150
+ - $ref: tool_definitions.confluence_tool
1151
+ ```
1152
+
1153
+ **Usage Options:**
1154
+
1155
+ ```yaml
1156
+ # Option 1: Use tool definitions (RECOMMENDED - cleanest & most explicit)
1157
+ tools:
1158
+ - $ref: tool_definitions.jira_tool
1159
+ - $ref: tool_definitions.confluence_tool
1160
+
1161
+ # Option 2: Reference integration directly (middle ground)
1162
+ tools:
1163
+ - name: generic_jira_tool
1164
+ settings:
1165
+ $ref: imported.integrations.jira_main
1166
+
1167
+ # Option 3: Inline everything (not recommended, verbose)
1168
+ tools:
1169
+ - name: generic_jira_tool
1170
+ settings:
1171
+ id: "9ab1ad26-07f1-4d1a-9b0b-33d33a9d2cde"
1172
+ credential_type: Jira
1173
+ # ... many more fields
1174
+ ```
1175
+
1176
+ **Benefits:**
1177
+ - ✅ **DRY Principle**: Define once, use everywhere
1178
+ - ✅ **Easy Updates**: Change integration/tool in one place
1179
+ - ✅ **Ultra Clean Config**: From 15+ lines to 1 line per tool
1180
+ - ✅ **Type Safety**: Integration/tool not found? Error at load time
1181
+ - ✅ **Reusability**: Share tools across multiple assistants
1182
+
1183
+ **Note:** Integrations are created and managed in Codemie UI. The IaC config only references them by ID.
1184
+
1185
+ **Basic Toolkit Structure:**
1186
+ ```yaml
1187
+ resources:
1188
+ assistants:
1189
+ - name: My Assistant
1190
+ model: gpt-4o
1191
+ toolkits:
1192
+ - toolkit: Git # Toolkit name
1193
+ label: ""
1194
+ settings_config: true
1195
+ is_external: false
1196
+ tools:
1197
+ - name: get_pr_changes
1198
+ label: "Get PR Changes"
1199
+ settings_config: false
1200
+ ```
1201
+
1202
+ **MCP (Model Context Protocol) Servers:**
1203
+
1204
+ In addition to toolkits, assistants can use MCP servers for external integrations. MCP servers use the same integration aliasing pattern as toolkits:
1205
+
1206
+ ```yaml
1207
+ imported:
1208
+ integrations:
1209
+ - alias: playwright_mcp
1210
+ id: "4fdd1ece-700e-43e2-8750-31bb482c61f1"
1211
+ credential_type: MCP
1212
+
1213
+ resources:
1214
+ assistants:
1215
+ - name: Browser Automation Assistant
1216
+ prompt: ./system_prompts/browser-automation.prompt.md
1217
+ description: "Assistant with browser automation via Playwright MCP"
1218
+ model: gpt-4o
1219
+ mcp_servers:
1220
+ - name: Playwright MCP Server
1221
+ description: "Playwright browser automation"
1222
+ enabled: true
1223
+ config:
1224
+ url: https://your-mcp-server.example.com/playwright/
1225
+ headers:
1226
+ X-Api-Key: $API_KEY
1227
+ settings:
1228
+ $ref: imported.integrations.playwright_mcp
1229
+ ```
1230
+
1231
+ **MCP Integration Aliasing:**
1232
+ - MCP integrations are defined once in `imported.integrations`
1233
+ - MCP servers reference them via `settings: { $ref: imported.integrations.alias }`
1234
+ - Same DRY pattern as toolkits - define once, use everywhere
1235
+
1236
+ > **🔧 For detailed MCP examples**, see the MCP section in `examples/toolkit-examples.yaml`
1237
+
1238
+ ### Workflows
1239
+
1240
+ Workflows orchestrate multiple assistants to handle complex, multi-step tasks.
1241
+
1242
+ #### Workflow Configuration in codemie.yaml
1243
+
1244
+ ```yaml
1245
+ resources:
1246
+ workflows:
1247
+ - name: My Workflow # No ID needed (name-based management)
1248
+ description: Workflow description
1249
+ definition: ./workflows/my-workflow.yaml # Path to workflow definition file
1250
+ mode: Sequential # Sequential or Autonomous
1251
+ shared: true # Share with project members
1252
+ ```
1253
+
1254
+ **Required fields:**
1255
+ - `name` - Unique workflow name (used as identifier)
1256
+ - `description` - Workflow description
1257
+ - `definition` - Path to workflow definition file
1258
+ - `mode` - Execution mode: `Sequential` or `Autonomous`
1259
+ - `shared` - Whether to share with project (typically `true`)
1260
+
1261
+ #### Workflow YAML Structure
1262
+
1263
+ Create a workflow definition file (e.g., `workflows/my-workflow.yaml`):
1264
+
1265
+ ```yaml
1266
+ assistants:
1267
+ # Reference assistants by NAME (name-based approach)
1268
+ - id: analyzer # Local ID for this workflow
1269
+ assistant_name: Data Analysis Assistant # References assistant from codemie.yaml
1270
+
1271
+ - id: reviewer # Local ID
1272
+ assistant_name: Code Reviewer # Another assistant reference
1273
+
1274
+ # Inline assistant (defined directly in workflow)
1275
+ - id: parser
1276
+ model: gpt-4o-mini
1277
+ name: Data Parser
1278
+ system_prompt: |
1279
+ You are a data parser. Extract structured data from text.
1280
+
1281
+ states:
1282
+ - id: first_step
1283
+ assistant_id: analyzer # Uses local ID from assistants section
1284
+ task: |
1285
+ Analyze the following input: {{ user_input }}
1286
+ output_schema: |
1287
+ {
1288
+ "analysis": "string",
1289
+ "confidence": "number",
1290
+ "recommendations": "array"
1291
+ }
1292
+ next:
1293
+ state_id: second_step
1294
+
1295
+ - id: second_step
1296
+ assistant_id: reviewer
1297
+ task: |
1298
+ Review the analysis: {{ analysis }}
1299
+ Provide feedback on: {{ recommendations }}
1300
+ output_schema: |
1301
+ {
1302
+ "feedback": "string",
1303
+ "approved": "boolean"
1304
+ }
1305
+ next:
1306
+ state_id: end
1307
+ ```
1308
+
1309
+ **How assistant resolution works:**
1310
+ 1. **External assistants** (with `assistant_name`):
1311
+ - IaC looks up in `state.json` (for IaC-managed assistants)
1312
+ - Falls back to `imported.assistants` (for platform-managed assistants)
1313
+ - Resolves name → UUID during deployment
1314
+ - Workflow YAML stays unchanged (portable!)
1315
+
1316
+ 2. **Inline assistants** (with `model` and `system_prompt`):
1317
+ - Defined directly in workflow
1318
+ - No resolution needed
1319
+ - Good for simple, workflow-specific assistants
1320
+
1321
+ **Change detection:**
1322
+ - **Workflow YAML checksum** (`workflowYamlChecksum`) - Detects changes to workflow logic
1323
+ - **Metadata checksum** (`configChecksum`) - Detects changes to name, description, mode
1324
+
1325
+ > **📚 For detailed workflow patterns**, see `examples/workflow-examples.yaml`
1326
+ > **📖 For best practices**, see [Workflow Configuration Documentation](https://kb.epam.com/display/EPMCDME/Workflow+configuration+documentation)
1327
+
1328
+ ### Linking Datasources to Assistants
1329
+
1330
+ You can link datasources to assistants using the `context` field:
1331
+
1332
+ ```yaml
1333
+ resources:
1334
+ datasources:
1335
+ - name: my-repo
1336
+ type: code
1337
+ description: "My repository"
1338
+ link: https://git.example.com/repo
1339
+ branch: master
1340
+ setting_id: $ref:imported.integrations.git_connection.id
1341
+
1342
+ assistants:
1343
+ - name: My Assistant
1344
+ prompt: ./system_prompts/assistant.prompt.md
1345
+ description: "Assistant with datasources"
1346
+ model: gpt-4o
1347
+ context:
1348
+ - context_type: code
1349
+ name: my-repo # Reference datasource by name
1350
+ ```
1351
+
1352
+ **How it works:**
1353
+ - Use `context` array to reference datasources by their `name` field
1354
+ - Specify `context_type` matching datasource type (`code`, `knowledge_base`, etc.)
1355
+ - During deployment, datasource names are resolved to platform IDs
1356
+ - Datasources must be defined in config (resources or imported) for resolution to work
1357
+
1358
+ **Example with imported datasources:**
1359
+
1360
+ ```yaml
1361
+ imported:
1362
+ datasources:
1363
+ - id: b31ac927-37ec-4038-bdcc-98fab5d76ec1
1364
+ name: Existing Jira KB
1365
+ type: knowledge_base_jira
1366
+
1367
+ resources:
1368
+ datasources:
1369
+ - name: my-code-repo
1370
+ type: code
1371
+ description: "My repository"
1372
+ link: https://git.example.com/repo
1373
+ branch: master
1374
+ setting_id: $ref:imported.integrations.git_connection.id
1375
+
1376
+ assistants:
1377
+ - name: My Assistant
1378
+ prompt: ./system_prompts/assistant.prompt.md
1379
+ model: gpt-4o
1380
+ context:
1381
+ - context_type: code
1382
+ name: my-code-repo # From resources (IaC-managed)
1383
+ - context_type: knowledge_base
1384
+ name: Existing Jira KB # From imported (platform-managed)
1385
+ ```
1386
+
1387
+ **💡 Use imported datasources when:**
1388
+ - Datasource is shared across multiple teams
1389
+ - You don't want to manage datasource lifecycle via IaC
1390
+ - Datasource already exists and is maintained elsewhere
1391
+
1392
+ ### Datasource Defaults with `$ref`
1393
+
1394
+ To avoid repetition, define reusable datasource configurations in `datasource_defaults` and reference them using `$ref`:
1395
+
1396
+ ```yaml
1397
+ datasource_defaults:
1398
+ code:
1399
+ type: code
1400
+ index_type: code
1401
+ embeddings_model: ada-002
1402
+ shared_with_project: true
1403
+ branch: master
1404
+ force_reindex: false
1405
+
1406
+ production_code:
1407
+ type: code
1408
+ index_type: summary
1409
+ embeddings_model: text-embedding-3-large
1410
+ shared_with_project: true
1411
+ branch: main
1412
+ force_reindex: false
1413
+
1414
+ jira:
1415
+ type: knowledge_base_jira
1416
+ embeddings_model: ada-002
1417
+ shared_with_project: true
1418
+ force_reindex: false
1419
+
1420
+ resources:
1421
+ datasources:
1422
+ # Explicit $ref - inherits ALL fields from code
1423
+ - $ref: datasource_defaults.code
1424
+ name: my-repo
1425
+ description: My Git repository
1426
+ link: https://git.example.com/repo
1427
+ setting_id: $ref:imported.integrations.git_conn.id
1428
+ # type, index_type, embeddings_model, branch, etc. from $ref!
1429
+
1430
+ # Override specific fields
1431
+ - $ref: datasource_defaults.code
1432
+ name: special-repo
1433
+ description: Special repository
1434
+ link: https://git.example.com/repo2
1435
+ setting_id: $ref:imported.integrations.git_conn.id
1436
+ branch: develop # ← Overrides "master" from defaults
1437
+ embeddings_model: text-embedding-3-large # ← Override
1438
+
1439
+ # Different defaults template
1440
+ - $ref: datasource_defaults.production_code
1441
+ name: prod-repo
1442
+ description: Production repository
1443
+ link: https://git.example.com/prod
1444
+ setting_id: $ref:imported.integrations.git_conn.id
1445
+ # Uses production_code settings (summary index, large embeddings)
1446
+
1447
+ # Jira datasource
1448
+ - $ref: datasource_defaults.jira
1449
+ name: my-jira
1450
+ description: Jira knowledge base
1451
+ setting_id: $ref:imported.integrations.jira_conn.id
1452
+ jql: project = MY
1453
+ ```
1454
+
1455
+ **How `$ref` defaults work:**
1456
+ - **Explicit reference**: `$ref: datasource_defaults.name` at the start of datasource
1457
+ - **Merge strategy**: `{ ...defaults, ...datasource }` - datasource fields override defaults
1458
+ - **Multiple templates**: Create different default sets for different use cases
1459
+ - **Minimal config**: Only specify fields unique to each datasource (name, link, description)
1460
+
1461
+ **Why `$ref` instead of type-based defaults?**
1462
+ 1. **Explicit** - Clear where values come from
1463
+ 2. **Flexible** - Multiple default sets for same type (e.g., code vs production_code)
1464
+ 3. **Reusable** - Same `$ref` mechanism as integrations and tools
1465
+ 4. **DRY** - Avoid repeating same fields across 30+ datasources
1466
+
1467
+ **Required fields** (for CODE datasources):
1468
+ - `name` - Unique datasource name
1469
+ - `type` - Datasource type (determines which defaults to use)
1470
+ - `description` - Description (typically repository info)
1471
+ - `link` - Git repository URL
1472
+ - `branch` - Git branch to index
1473
+
1474
+ **Common fields** (typically in defaults):
1475
+ - `index_type` - Indexing type: `code`, `summary`, or `chunk-summary`
1476
+ - `embeddings_model` - Model for embeddings (e.g., `ada-002`)
1477
+ - `summarization_model` - LLM model for summarization (e.g., `gpt-4o`)
1478
+ - `shared_with_project` - Share with project (default: `true`)
1479
+ - `setting_id` - Integration reference (use `$ref:imported.integrations.name.id`)
1480
+ - `force_reindex` - Force full reindex on deploy (default: `false`)
1481
+
1482
+ **Force Reindex:**
1483
+ Set `force_reindex: true` to trigger a full reindex of the datasource on the next deployment, even if no configuration changes were detected. This is useful for:
1484
+ - Updating the index with new commits from the repository
1485
+ - Recovering from failed indexing
1486
+ - Applying new embeddings model settings
1487
+
1488
+ After deployment, set it back to `false` to avoid unnecessary reindexing.
1489
+
1490
+ **Note:** Datasource creation starts background indexing. Check Codemie UI for indexing status.
1491
+
1492
+ > **📚 For detailed datasource examples**, see `examples/datasource-examples.yaml` with all available fields, descriptions, and common patterns.
1493
+
1494
+ ### Reusing Prompts
1495
+
1496
+ Multiple assistants can share the same prompt file:
1497
+
1498
+ ```yaml
1499
+ assistants:
1500
+ - name: Production Bot
1501
+ prompt: system_prompts/shared.prompt.md
1502
+ model: gpt-4o
1503
+
1504
+ - name: Development Bot (Copy)
1505
+ prompt: system_prompts/shared.prompt.md # Same file
1506
+ model: gpt-4o-mini
1507
+ ```
1508
+
1509
+ **Use cases:**
1510
+ - ✅ Creating test/staging copies of production assistants
1511
+ - ✅ A/B testing with different models but same prompt
1512
+ - ✅ Team-specific variants with shared core logic
1513
+ - ✅ Backup/rollback scenarios
1514
+
1515
+ ## 🔄 Common Workflows
1516
+
1517
+ ### Adding a New Assistant
1518
+
1519
+ 1. **Create prompt file:**
1520
+ ```bash
1521
+ touch system_prompts/my-new-assistant.prompt.md
1522
+ ```
1523
+
1524
+ 2. **Add to `codemie.yaml`:**
1525
+ ```yaml
1526
+ resources:
1527
+ assistants:
1528
+ - name: My New Assistant # Used as identifier (NO ID!)
1529
+ prompt: ./system_prompts/my-new-assistant.prompt.md
1530
+ description: "Description here"
1531
+ model: gpt-4o
1532
+ temperature: 0.7
1533
+ shared: true
1534
+ toolkits: []
1535
+ context: []
1536
+ ```
1537
+
1538
+ 3. **Deploy:**
1539
+ ```bash
1540
+ npm run validate # Check slug conflicts (if slug provided)
1541
+ npm run preview # Preview changes
1542
+ npm run deploy # Create assistant
1543
+ ```
1544
+
1545
+ **✨ After deploy:**
1546
+ - `codemie.yaml` **remains unchanged** (no ID added)
1547
+ - `.codemie/state.json` is updated with name→ID mapping
1548
+
1549
+ ### Updating an Assistant
1550
+
1551
+ 1. **Edit the prompt file** or settings in `codemie.yaml`
1552
+ 2. **Run preview** to see changes:
1553
+ ```bash
1554
+ npm run preview
1555
+ ```
1556
+ 3. **Deploy:**
1557
+ ```bash
1558
+ npm run deploy
1559
+ ```
1560
+
1561
+ ### Adding a New Workflow
1562
+
1563
+ 1. **Create workflow YAML file:**
1564
+ ```bash
1565
+ touch workflows/my-workflow.yaml
1566
+ ```
1567
+
1568
+ 2. **Define workflow** in `workflows/my-workflow.yaml`:
1569
+ ```yaml
1570
+ assistants:
1571
+ # Reference assistants by NAME (from codemie.yaml)
1572
+ - id: step1
1573
+ assistant_name: My Assistant
1574
+ - id: step2
1575
+ assistant_name: Another Assistant
1576
+
1577
+ states:
1578
+ - id: first_step
1579
+ assistant_id: step1
1580
+ task: "Analyze: {{ user_input }}"
1581
+ output_schema: '{ "result": "string" }'
1582
+ next:
1583
+ state_id: second_step
1584
+ - id: second_step
1585
+ assistant_id: step2
1586
+ task: "Process: {{ result }}"
1587
+ output_schema: '{ "final": "string" }'
1588
+ next:
1589
+ state_id: end
1590
+ ```
1591
+
1592
+ 3. **Add to `codemie.yaml`:**
1593
+ ```yaml
1594
+ resources:
1595
+ workflows:
1596
+ - name: My Workflow # No ID yet
1597
+ description: "Workflow description"
1598
+ definition: ./workflows/my-workflow.yaml
1599
+ mode: Sequential
1600
+ shared: true
1601
+ ```
1602
+
1603
+ 4. **Deploy:**
1604
+ ```bash
1605
+ npm run preview # Preview changes
1606
+ npm run deploy # Create workflow
1607
+ ```
1608
+
1609
+ **✨ After deploy:**
1610
+ - `codemie.yaml` **remains unchanged** (no ID added)
1611
+ - `.codemie/state.json` is updated with name→ID mapping
1612
+
1613
+ ## Scenarios
1614
+
1615
+ This section covers 18 real-world scenarios you'll encounter when managing resources with IaC.
1616
+
1617
+ ### 📑 Quick Reference Table
1618
+
1619
+ | Scenario | What It Covers | Risk Level | Auto-Recovery |
1620
+ |----------|---------------|------------|---------------|
1621
+ | [1. Create New Assistant](#scenario-1-create-new-assistant) | Initial resource creation | ✅ Safe | N/A |
1622
+ | [2. Update Assistant Prompt](#scenario-2-update-assistant-prompt) | Modify prompt content | ✅ Safe | N/A |
1623
+ | [3. Update Assistant Config](#scenario-3-update-assistant-config) | Modify settings/toolkits | ✅ Safe | N/A |
1624
+ | [4. Rename Assistant](#scenario-4-rename-assistant) | Delete old + create new | ⚠️ **Breaking** | ❌ No |
1625
+ | [5. Delete Assistant](#scenario-5-delete-assistant) | Automatic cleanup | ⚠️ Destructive | ❌ No |
1626
+ | [6. Sub-Assistants](#scenario-6-assistant-references-another-sub-assistants) | Dependency management | ✅ Safe | N/A |
1627
+ | [7. Workflow References](#scenario-7-workflow-references-assistant) | Name-based resolution | ✅ Safe | N/A |
1628
+ | [8. Imported Assistant](#scenario-8-workflow-references-imported-assistant) | External references | ✅ Safe | N/A |
1629
+ | [9. Datasource Reference](#scenario-9-datasource-referenced-by-assistant) | Context linking | ✅ Safe | N/A |
1630
+ | [10. Integration Reuse](#scenario-10-integration-used-by-multiple-resources) | `$ref` mechanism | ✅ Safe | N/A |
1631
+ | [11. Manual Change](#scenario-11-manual-platform-change-detected) | Drift detection | ⚠️ Overwrites | ✅ Auto-reverts |
1632
+ | [12. State Deleted](#scenario-12-statejson-deletedcorrupted) | Recovery options | 🔴 **Critical** | ❌ Manual fix |
1633
+ | [13. Parallel Workflow](#scenario-13-parallel-workflow-in-gitlab-prevented) | CI/CD protection | ✅ Safe | N/A |
1634
+ | [14. Field Transformation](#scenario-14-config-field-name-transformation) | SDK compatibility | ✅ Safe | N/A |
1635
+ | [15. Missing Prompt](#scenario-15-prompt-file-missing) | Validation error | ✅ Safe | ❌ Manual fix |
1636
+ | [16. Circular Dependency](#scenario-16-circular-dependency) | Validation error | ✅ Safe | ❌ Manual fix |
1637
+ | [17. Nested Sub-Assistants](#scenario-17-nested-sub-assistants-not-allowed) | Platform limitation | ✅ Safe | ❌ Manual fix |
1638
+ | [18. Missing Env Var](#scenario-18-environment-variable-missing) | Configuration error | ⚠️ Deploy fails | ❌ Manual fix |
1639
+
1640
+ ### Scenario 1: Create New Assistant
1641
+
1642
+ **Config (codemie.yaml):**
1643
+ ```yaml
1644
+ resources:
1645
+ assistants:
1646
+ - name: Code Reviewer
1647
+ prompt: system_prompts/code-reviewer.prompt.md
1648
+ model: gpt-4o
1649
+ description: Reviews code for best practices
1650
+ ```
1651
+
1652
+ **What happens:**
1653
+ 1. `npm run validate` - Checks prompt file exists
1654
+ 2. `npm run preview` - Shows "Create: 1 assistant"
1655
+ 3. `npm run deploy`:
1656
+ - Creates assistant via SDK
1657
+ - Gets UUID back from platform
1658
+ - Calculates checksums for prompt and config
1659
+ - Saves to state.json: `"Code Reviewer": { id: "uuid", promptChecksum: "...", configChecksum: "..." }`
1660
+
1661
+ ### Scenario 2: Update Assistant Prompt
1662
+
1663
+ **Change:** Modify `system_prompts/code-reviewer.prompt.md`
1664
+
1665
+ **What happens:**
1666
+ 1. `npm run preview` - Detects prompt checksum changed
1667
+ 2. `npm run deploy`:
1668
+ - Recalculates prompt checksum
1669
+ - Compares with stored checksum → different
1670
+ - Calls `assistants.update(uuid, { ...config, system_prompt: newContent })`
1671
+ - Updates promptChecksum in state.json
1672
+
1673
+ ### Scenario 3: Update Assistant Config
1674
+
1675
+ **Change:** Add toolkit to assistant in `codemie.yaml`
1676
+
1677
+ **What happens:**
1678
+ 1. `npm run preview` - Detects config checksum changed
1679
+ 2. `npm run deploy`:
1680
+ - Recalculates config checksum (based on all fields except prompt path)
1681
+ - Compares with stored checksum → different
1682
+ - Calls `assistants.update(uuid, newConfig)`
1683
+ - Updates configChecksum in state.json
1684
+
1685
+ ### Scenario 4: Rename Assistant
1686
+
1687
+ **Change:** `name: Code Reviewer` → `name: Senior Code Reviewer`
1688
+
1689
+ **What happens:**
1690
+ 1. `npm run preview` - Shows "Delete: Code Reviewer, Create: Senior Code Reviewer"
1691
+ 2. `npm run deploy`:
1692
+ - Looks up "Senior Code Reviewer" in state.json → not found → treats as new resource
1693
+ - Creates "Senior Code Reviewer" with new UUID
1694
+ - Detects "Code Reviewer" is in state but not in config → orphaned
1695
+ - If `--prune` is NOT set:
1696
+ - Reports orphan but does NOT delete "Code Reviewer"
1697
+ - State now has both (but "Code Reviewer" is still tracked as orphan)
1698
+ - If `--prune` IS set:
1699
+ - Deletes "Code Reviewer" from platform
1700
+ - State now has only "Senior Code Reviewer"
1701
+
1702
+ **Note:** All references to old name break (e.g., in workflows). Update references before renaming.
1703
+
1704
+ ### Scenario 5: Delete Assistant
1705
+
1706
+ **Change:** Remove assistant from `codemie.yaml`
1707
+
1708
+ **What happens:**
1709
+ 1. `npm run preview` - Shows "Delete: 1 assistant"
1710
+ 2. `npm run deploy`:
1711
+ - Detects assistant in state.json but not in config
1712
+ - If `--prune` IS set:
1713
+ - Deletes from platform using stored UUID
1714
+ - Removes from state.json
1715
+ - If `--prune` is NOT set:
1716
+ - Warns about orphaned resource
1717
+ - Assistant remains on platform and in state.json
1718
+
1719
+ ### Scenario 6: Assistant References Another (Sub-Assistants)
1720
+
1721
+ **Config:**
1722
+ ```yaml
1723
+ resources:
1724
+ assistants:
1725
+ - name: Data Validator
1726
+ prompt: system_prompts/validator.prompt.md
1727
+ model: gpt-4o-mini
1728
+
1729
+ - name: Data Processor
1730
+ prompt: system_prompts/processor.prompt.md
1731
+ model: gpt-4o
1732
+ sub_assistants:
1733
+ - Data Validator # Name reference, not UUID
1734
+ ```
1735
+
1736
+ **What happens:**
1737
+ 1. `npm run validate` - Checks "Data Validator" exists in config
1738
+ 2. `npm run deploy`:
1739
+ - Deploys assistants in order (Data Validator first, then Data Processor)
1740
+ - When deploying Data Processor:
1741
+ - Looks up "Data Validator" in state.json → gets UUID
1742
+ - Adds UUID to `assistant_ids` array for API call
1743
+ - Both assistants now in state.json
1744
+
1745
+ **Dependency order:** IaC automatically processes assistants in dependency order (sub-assistants before parents).
1746
+
1747
+ ### Scenario 7: Workflow References Assistant
1748
+
1749
+ **Workflow YAML (workflows/my-workflow.yaml):**
1750
+ ```yaml
1751
+ assistants:
1752
+ - id: reviewer
1753
+ assistant_name: Code Reviewer # Name, not UUID
1754
+
1755
+ states:
1756
+ - id: review
1757
+ assistant_id: reviewer
1758
+ task: Review the code
1759
+ is_final: true
1760
+ ```
1761
+
1762
+ **Config (codemie.yaml):**
1763
+ ```yaml
1764
+ resources:
1765
+ workflows:
1766
+ - name: Code Review Workflow
1767
+ definition: workflows/my-workflow.yaml
1768
+ mode: Sequential
1769
+ ```
1770
+
1771
+ **What happens:**
1772
+ 1. `npm run deploy`:
1773
+ - Loads workflow YAML
1774
+ - Finds `assistant_name: Code Reviewer`
1775
+ - Looks up in state.json → gets UUID
1776
+ - Replaces with `assistant_id: uuid`
1777
+ - Sends modified YAML to API
1778
+ - Stores workflow in state.json
1779
+
1780
+ ### Scenario 8: Workflow References Imported Assistant
1781
+
1782
+ **Config:**
1783
+ ```yaml
1784
+ imported:
1785
+ assistants:
1786
+ - id: external-assistant-uuid
1787
+ name: External Tool
1788
+
1789
+ resources:
1790
+ workflows:
1791
+ - name: My Workflow
1792
+ definition: workflows/workflow.yaml
1793
+ ```
1794
+
1795
+ **Workflow YAML:**
1796
+ ```yaml
1797
+ assistants:
1798
+ - id: step1
1799
+ assistant_name: External Tool # References imported assistant
1800
+ ```
1801
+
1802
+ **What happens:**
1803
+ 1. `npm run deploy`:
1804
+ - Looks up "External Tool" in state.json → not found
1805
+ - Looks up in `imported.assistants` → found with UUID
1806
+ - Uses that UUID for workflow
1807
+ - Deploys workflow successfully
1808
+
1809
+ ### Scenario 9: Datasource Referenced by Assistant
1810
+
1811
+ **Config:**
1812
+ ```yaml
1813
+ resources:
1814
+ datasources:
1815
+ - name: my-repo
1816
+ type: code
1817
+ link: https://git.example.com/repo
1818
+ setting_id: $ref:imported.integrations.git_connection.id
1819
+
1820
+ assistants:
1821
+ - name: Code Assistant
1822
+ prompt: system_prompts/assistant.prompt.md
1823
+ model: gpt-4o
1824
+ context:
1825
+ - context_type: code
1826
+ name: my-repo # Datasource name reference
1827
+ ```
1828
+
1829
+ **What happens:**
1830
+ 1. `npm run deploy`:
1831
+ - Deploys datasource first (dependency order)
1832
+ - Deploys assistant with context pointing to datasource name
1833
+ - Platform resolves datasource name to UUID internally
1834
+
1835
+ ### Scenario 10: Integration Used by Multiple Resources
1836
+
1837
+ **Config:**
1838
+ ```yaml
1839
+ imported:
1840
+ integrations:
1841
+ - alias: jira_conn
1842
+ id: jira-uuid
1843
+ credential_type: Jira
1844
+
1845
+ resources:
1846
+ datasources:
1847
+ - name: jira-data
1848
+ type: knowledge_base_jira
1849
+ jql: project = MY
1850
+ setting_id: $ref:imported.integrations.jira_conn # Reference 1
1851
+
1852
+ assistants:
1853
+ - name: Jira Bot
1854
+ toolkits:
1855
+ - toolkit: jira
1856
+ settings: $ref:imported.integrations.jira_conn # Reference 2
1857
+ ```
1858
+
1859
+ **What happens:**
1860
+ - During config load, both `$ref` are resolved to same integration object
1861
+ - Changes to `jira_conn` automatically apply to all references
1862
+ - No ID duplication in config
1863
+
1864
+ ### Scenario 11: Manual Platform Change Detected
1865
+
1866
+ **Situation:** Someone manually edits assistant on platform (e.g., changes temperature)
1867
+
1868
+ **What happens:**
1869
+ 1. `npm run preview` - Compares config checksums with state
1870
+ - Prompt unchanged → prompt checksum matches
1871
+ - Config unchanged → config checksum matches
1872
+ - Shows "Unchanged: 0, Update: 0"
1873
+ 2. Manual change NOT detected (by design)
1874
+ 3. Next `npm run deploy` with ANY config change:
1875
+ - IaC pushes config version
1876
+ - Manual change overwritten
1877
+
1878
+ **Why?** Config is source of truth. IaC doesn't detect drift, only manages config→platform flow.
1879
+
1880
+ ### Scenario 12: State.json Deleted/Corrupted
1881
+
1882
+ **What happens:**
1883
+ 1. `npm run preview` - Cannot find resources in state → treats all as new
1884
+ - Shows "Create: 10 assistants" (even though they exist)
1885
+ 2. `npm run deploy` - Attempts to create all resources
1886
+ - Platform rejects duplicates (if names conflict)
1887
+ - Or creates new resources with same names (depending on platform)
1888
+
1889
+ **Recovery:**
1890
+ 1. Restore state.json from Git history: `git checkout HEAD~1 -- .codemie/state.json`
1891
+ 2. Or manually reconstruct state by fetching UUIDs from platform and building state.json
1892
+
1893
+ ### Scenario 13: Parallel Workflow in GitLab (Prevented)
1894
+
1895
+ **Setup:**
1896
+ ```yaml
1897
+ deploy:
1898
+ resource_group: production # KEY: Ensures sequential execution
1899
+ ```
1900
+
1901
+ **What happens:**
1902
+ 1. Developer A merges PR → triggers pipeline A
1903
+ 2. Developer B merges PR 10 seconds later → triggers pipeline B
1904
+ 3. GitLab sees `resource_group: production`:
1905
+ - Pipeline B waits for pipeline A to complete
1906
+ - No concurrent access to state.json
1907
+ - No race conditions
1908
+
1909
+ ### Scenario 14: Config Field Name Transformation
1910
+
1911
+ **Config (what you write):**
1912
+ ```yaml
1913
+ datasources:
1914
+ - name: my-repo
1915
+ type: code
1916
+ link: https://git.example.com/repo # Config uses 'link'
1917
+ setting_id: $ref:... # Config uses 'setting_id'
1918
+ ```
1919
+
1920
+ **What IaC does internally:**
1921
+ - Reads `link` and `setting_id` from config
1922
+ - API call unchanged (uses same fields)
1923
+ - Backward compatibility: Also accepts `repository_url` → auto-converts to `link`
1924
+
1925
+ **Why?** Config field names match SDK/API expectations for consistency.
1926
+
1927
+ ### Scenario 15: Prompt File Missing
1928
+
1929
+ **Config:**
1930
+ ```yaml
1931
+ assistants:
1932
+ - name: My Bot
1933
+ prompt: system_prompts/missing.prompt.md # File doesn't exist
1934
+ ```
1935
+
1936
+ **What happens:**
1937
+ 1. `npm run validate` - Checks file existence → fails
1938
+ ```
1939
+ Error: Prompt file not found: system_prompts/missing.prompt.md (referenced by assistant: My Bot)
1940
+ ```
1941
+ 2. Deployment blocked until file created
1942
+
1943
+ ### Scenario 16: Circular Dependency
1944
+
1945
+ **Config:**
1946
+ ```yaml
1947
+ assistants:
1948
+ - name: Assistant A
1949
+ sub_assistants: [Assistant B]
1950
+ - name: Assistant B
1951
+ sub_assistants: [Assistant A] # Circular!
1952
+ ```
1953
+
1954
+ **What happens:**
1955
+ 1. `npm run validate` - DFS cycle detection → fails
1956
+ ```
1957
+ Error: Cyclic dependency detected: Assistant A → Assistant B → Assistant A
1958
+ ```
1959
+ 2. Deployment blocked until cycle removed
1960
+
1961
+ ### Scenario 17: Nested Sub-Assistants (Not Allowed)
1962
+
1963
+ **Config:**
1964
+ ```yaml
1965
+ assistants:
1966
+ - name: Helper
1967
+ sub_assistants: [Specialist] # Helper has sub-assistant
1968
+ - name: Main
1969
+ sub_assistants: [Helper] # Main uses Helper (which has sub-assistant)
1970
+ ```
1971
+
1972
+ **What happens:**
1973
+ 1. `npm run validate` - Detects nested sub-assistants → fails
1974
+ ```
1975
+ Error: Assistant "Helper" has sub-assistants but is itself used as a sub-assistant by: Main.
1976
+ Nested sub-assistants are not allowed.
1977
+ ```
1978
+ 2. Flatten hierarchy: Main should directly reference both Helper and Specialist
1979
+
1980
+ ### Scenario 18: Environment Variable Missing
1981
+
1982
+ **Config:**
1983
+ ```yaml
1984
+ environment:
1985
+ codemie_api_url: ${CODEMIE_API_URL}
1986
+ ```
1987
+
1988
+ **What happens if `CODEMIE_API_URL` not set:**
1989
+ 1. `npm run validate` - Env var substitution → empty string
1990
+ 2. Connection fails with unclear error
1991
+ 3. **Best practice:** Check required env vars at script start
1992
+
1993
+ ## 🗄️ Backup & Restore
1994
+
1995
+ ### Creating Backups
1996
+
1997
+ The backup tool creates a complete snapshot of ALL resources in your Codemie instance:
1998
+
1999
+ ```bash
2000
+ npm run backup
2001
+ ```
2002
+
2003
+ **What gets backed up:**
2004
+ - ✅ **All Assistants** - Including prompts, toolkits, context, MCP servers, sub-assistants
2005
+ - ✅ **All Datasources** - CODE, Confluence, Jira, Google Docs with full configuration
2006
+ - ✅ **All Workflows** - YAML definitions, mode, and metadata
2007
+ - ✅ **All Integrations** - Project integrations (IDs and configuration)
2008
+ - ✅ **Complete State** - Full `state.json` with checksums for all resources
2009
+
2010
+ **Transaction Safety:**
2011
+ - Atomic backup process with rollback on failure
2012
+ - Resume capability - if backup is interrupted, rerunning continues from last checkpoint
2013
+ - Temporary directory used during backup (`.temp-*`) - moved to final location only on success
2014
+ - Progress tracking with `transaction.json` checkpoint file
2015
+
2016
+ **Output structure:**
2017
+ ```
2018
+ backups/
2019
+ └── 2025-10-22T14-30-45/ # Timestamp-based directory
2020
+ ├── backup.json # Complete backup with all data
2021
+ ├── state.json # State file (ready for IaC)
2022
+ ├── codemie.yaml # Reconstructed IaC config
2023
+ ├── system_prompts/ # Individual prompt files
2024
+ │ ├── assistant-1.prompt.md
2025
+ │ └── assistant-2.prompt.md
2026
+ ├── workflows/ # Individual workflow files
2027
+ │ ├── workflow-1.yaml
2028
+ │ └── workflow-2.yaml
2029
+ └── openapi_specs/ # OpenAPI specifications (if any)
2030
+ ├── sumo-logic-api.yaml
2031
+ ├── gitlab-api.yaml
2032
+ └── coda-api.yaml
2033
+ ```
2034
+
2035
+ ### Backup Contents
2036
+
2037
+ **1. backup.json** - Complete resource data
2038
+ - Full details of all assistants, datasources, workflows, and integrations
2039
+ - Used for selective restore or manual recovery
2040
+
2041
+ **2. state.json** - IaC state file
2042
+ - Resource name → UUID mappings
2043
+ - Checksums for change detection
2044
+ - Ready to use with `npm run deploy`
2045
+
2046
+ **3. codemie.yaml** - Reconstructed IaC configuration
2047
+ - Converts backup into IaC format
2048
+ - References individual prompt/workflow files
2049
+ - Includes all integrations in `imported` section
2050
+ - MCP servers use integration aliasing (`settings: { $ref: imported.integrations.alias }`)
2051
+
2052
+ **4. system_prompts/** - Individual prompt files
2053
+ - Each assistant's prompt as separate `.prompt.md` file
2054
+
2055
+ **5. workflows/** - Individual workflow definitions
2056
+ - Each workflow as separate `.yaml` file
2057
+
2058
+ **6. openapi_specs/** - OpenAPI specifications (if any)
2059
+ - Extracted from integrations and assistant toolkits
2060
+ - Stored as separate files (YAML or JSON)
2061
+ - File references used in codemie.yaml instead of embedding full specs
2062
+
2063
+ ### Restore Options
2064
+
2065
+ #### Option 1: Full Restore via IaC (Recommended)
2066
+
2067
+ Best for disaster recovery or environment migration:
2068
+
2069
+ ```bash
2070
+ # 1. Copy backup to workspace
2071
+ cp -r backups/2025-10-22T14-30-45/* /path/to/iac-workspace/
2072
+
2073
+ # 2. Review and adjust codemie.yaml
2074
+ # - Update project name if needed
2075
+ # - Update integration IDs for target environment
2076
+ # - Remove resources you don't want to restore
2077
+
2078
+ # 3. Copy state file
2079
+ cp state.json .codemie/state.json
2080
+
2081
+ # 4. Preview changes
2082
+ npm run preview
2083
+
2084
+ # 5. Deploy
2085
+ npm run deploy
2086
+ ```
2087
+
2088
+ **Important:**
2089
+ - Integration IDs are environment-specific (create integrations first in target environment)
2090
+ - Update `imported.integrations` section with new IDs
2091
+ - Review datasource `setting_id` fields (must match target environment integrations)
2092
+
2093
+ #### Option 2: Selective Restore
2094
+
2095
+ Restore specific resources using `backup.json`:
2096
+
2097
+ ```typescript
2098
+ import { CodeMieClient } from 'codemie-sdk';
2099
+ import * as fs from 'fs';
2100
+
2101
+ const backup = JSON.parse(fs.readFileSync('backup.json', 'utf8'));
2102
+
2103
+ // Restore specific assistant
2104
+ const assistant = backup.resources.assistants.find(a => a.name === 'Code Reviewer');
2105
+ await client.assistants.create({
2106
+ name: assistant.name,
2107
+ description: assistant.description,
2108
+ system_prompt: assistant.system_prompt,
2109
+ llm_model_type: assistant.llm_model_type,
2110
+ // ... other fields
2111
+ });
2112
+ ```
2113
+
2114
+ #### Option 3: Manual Restore via UI
2115
+
2116
+ Use backup as reference to manually recreate resources:
2117
+
2118
+ 1. Open `backup.json` in editor
2119
+ 2. For each resource:
2120
+ - Copy configuration fields
2121
+ - Create resource in Codemie UI
2122
+ - Paste prompt/workflow content
2123
+ - Configure toolkits/integrations
2124
+
2125
+ ### Backup Best Practices
2126
+
2127
+ **Regular Backups**
2128
+ ```bash
2129
+ # Daily backup (add to cron/CI)
2130
+ 0 2 * * * cd /path/to/iac && npm run backup
2131
+
2132
+ # Pre-deployment backup
2133
+ npm run backup && npm run deploy
2134
+ ```
2135
+
2136
+ **Backup Retention**
2137
+ ```bash
2138
+ # Keep last 30 days
2139
+ find backups/ -type d -mtime +30 -exec rm -rf {} +
2140
+ ```
2141
+
2142
+ **Version Control**
2143
+ - ✅ **Commit state.json** - Team visibility, CI/CD integration
2144
+ - ❌ **Don't commit backups/** - Large files, sensitive data
2145
+ - ✅ **Add to .gitignore**: `backups/`
2146
+
2147
+ **Sensitive Data**
2148
+ - **SDK automatically masks credentials** - Integration credentials appear as `"**********"` in backups
2149
+ - **Store backups securely** - Use encrypted storage and access control (backups contain prompts, configurations, and may contain other sensitive data)
2150
+
2151
+ ### Backup vs State.json
2152
+
2153
+ | Feature | backup.json | state.json |
2154
+ |---------|------------|------------|
2155
+ | **Content** | Full resource data | IDs + checksums only |
2156
+ | **Size** | Large (prompts, configs) | Small (metadata) |
2157
+ | **Use Case** | Disaster recovery, migration | Normal IaC operations |
2158
+ | **Git** | ❌ Don't commit | ✅ Commit |
2159
+ | **Portability** | ✅ Standalone | ❌ Requires codemie.yaml |
2160
+
2161
+ ### Troubleshooting
2162
+
2163
+ **Issue: Backup interrupted**
2164
+ - Just run `npm run backup` again - it will resume from last checkpoint
2165
+ - Transaction file (`transaction.json`) tracks progress
2166
+ - Temporary directory (`.temp-*`) will be cleaned up automatically
2167
+
2168
+ **Issue: Backup failed completely**
2169
+ - Check `.temp-*` directory exists - if yes, partial backup was attempted
2170
+ - Error message will indicate which resource failed
2171
+ - Temporary directory will be automatically cleaned up (rollback)
2172
+ - Fix the issue and rerun backup
2173
+
2174
+ **Issue: Want to force fresh backup (skip resume)**
2175
+ - Delete `transaction.json` from temporary directory before rerunning
2176
+ - Or delete entire `.temp-*` directory to start from scratch
2177
+
2178
+ **Issue: Backup fails with "Not Found" error**
2179
+ - Check API credentials in `.env`
2180
+ - Verify service account has access to all resources
2181
+ - Some resources may have been deleted on platform
2182
+
2183
+ **Issue: Integration IDs don't match after restore**
2184
+ - Integrations are environment-specific
2185
+ - Create integrations in target environment first
2186
+ - Update `imported.integrations` with new IDs
2187
+
2188
+ **Issue: Large backup file size**
2189
+ - Normal for many assistants with large prompts
2190
+ - Consider selective backup if needed
2191
+ - Backup tool fetches full resource details
2192
+
2193
+ **Issue: Code datasource missing repository link**
2194
+ - Some code datasources may show warning during backup
2195
+ - SDK sometimes doesn't return repository URL
2196
+ - Manually add `link: https://github.com/...` in restored codemie.yaml
2197
+
2198
+ **Issue: Workflow assistant IDs not resolved to names**
2199
+ - If workflow YAML contains `assistant_id: ast-xxx` instead of assistant name
2200
+ - This happens when assistant doesn't exist in backup (e.g., deleted or from another project)
2201
+ - Manually replace with correct assistant name in workflow YAML file
2202
+
2203
+ ## Advanced Topics
2204
+
2205
+ ### Deployment Order
2206
+
2207
+ Resources are deployed in dependency order:
2208
+
2209
+ 1. **Datasources** - No dependencies, can be created first
2210
+ 2. **Sub-Assistants** - May reference datasources via `context`
2211
+ 3. **Main Assistants** - May reference sub-assistants and datasources
2212
+ 4. **Workflows** - Reference assistants
2213
+
2214
+ **Implementation:** Sequential processing in `src/deploy.ts`. Dependencies validated at validation time.
2215
+
2216
+ ### Reusing Prompts
2217
+
2218
+ Multiple assistants can share the same prompt file:
2219
+
2220
+ ```yaml
2221
+ assistants:
2222
+ - name: Production Bot
2223
+ prompt: system_prompts/shared.prompt.md
2224
+ model: gpt-4o
2225
+
2226
+ - name: Development Bot (Copy)
2227
+ prompt: system_prompts/shared.prompt.md # Same file
2228
+ model: gpt-4o-mini
2229
+ ```
2230
+
2231
+ **Use case:** Testing variations (different models, temperatures) with same prompt.
2232
+
2233
+ ### Finding Assistants for Import
2234
+
2235
+ To reference existing platform assistants in workflows:
2236
+
2237
+ **API Endpoints:**
2238
+ - **List Assistants**: `GET /v1/assistants?per_page=100&project=project-name`
2239
+ - **Get Assistant by ID**: `GET /v1/assistants/id/{id}` (⚠️ 404 if assistant doesn't exist!)
2240
+
2241
+ **Example: Finding Assistants by Name**
2242
+
2243
+ ```typescript
2244
+ import axios from 'axios';
2245
+
2246
+ async function findAssistants(token: string, keywords: string[]) {
2247
+ const url = `${CODEMIE_API_URL}/v1/assistants`;
2248
+ const response = await axios.get(url, {
2249
+ headers: { 'Authorization': `Bearer ${token}` },
2250
+ params: { per_page: 100, project: 'ta-desk' }
2251
+ });
2252
+
2253
+ const assistants = response.data.assistants || response.data.data || response.data;
2254
+
2255
+ // Filter by keywords
2256
+ return assistants.filter((a: any) => {
2257
+ const name = (a.name || '').toLowerCase();
2258
+ return keywords.some(k => name.includes(k.toLowerCase()));
2259
+ });
2260
+ }
2261
+
2262
+ // Usage
2263
+ const matches = await findAssistants(token, ['test', 'checklist', 'jira']);
2264
+ matches.forEach((a: any) => {
2265
+ console.log(`• ${a.name} (ID: ${a.id}, Slug: ${a.slug || 'N/A'})`);
2266
+ });
2267
+ ```
2268
+
2269
+ **Adding to imported.assistants:**
2270
+
2271
+ ```yaml
2272
+ # After finding the assistant IDs
2273
+ imported:
2274
+ assistants:
2275
+ - id: 96e2d32a-1fe3-483c-b444-4afec9134928 # From API
2276
+ name: Checklist Generator Assistant # Exact name from API
2277
+ - id: ad45518d-411b-45e8-a087-e88a2c28a03f
2278
+ name: Jira Test Management Assistant
2279
+ ```
2280
+
2281
+ **⚠️ Important:**
2282
+ - **Assistant must exist on platform** - IaC will fail with 404 if ID is invalid
2283
+ - **Use exact names** - Workflow resolution is case-sensitive
2284
+ - **Verify access** - Service account must have permission to use the assistant
2285
+ - **Check regularly** - Imported assistants can be deleted by their owners
2286
+
2287
+ ### Working with Codemie API Directly
2288
+
2289
+ If you need to fetch assistant or datasource data directly from the API:
2290
+
2291
+ **API Endpoints:**
2292
+ - **Get Assistant by ID**: `GET /v1/assistants/id/{id}`
2293
+ - **List Datasources**: `GET /v1/index?filters={"project":["project-name"]}`
2294
+
2295
+ **Important Field Mappings:**
2296
+
2297
+ When reading datasources from API:
2298
+ - API returns `repo_name` → Use as `name` in config
2299
+ - API returns `index_type` → Use as `type` in config
2300
+ - API returns `link` → Use as `link` in config (Git repository URL)
2301
+ - API returns `setting_id` → Use as `setting_id` in config (integration ID)
2302
+
2303
+ When deploying datasources from config:
2304
+ - Config `link` → API `link` (no mapping needed)
2305
+ - Config `setting_id` → API `setting_id` (no mapping needed)
2306
+ - For Jira: Config `jql` → API `jql` (flat structure)
2307
+ - For Confluence: Config `cql` → API `cql` (flat structure)
2308
+
2309
+ **Example: Fetching Assistant Data**
2310
+
2311
+ ```typescript
2312
+ // Get token
2313
+ const tokenUrl = `${CODEMIE_AUTH_URL}/realms/${CODEMIE_REALM}/protocol/openid-connect/token`;
2314
+ const params = new URLSearchParams({
2315
+ grant_type: 'client_credentials',
2316
+ client_id: CODEMIE_CLIENT_ID,
2317
+ client_secret: CODEMIE_CLIENT_SECRET,
2318
+ });
2319
+ const tokenResponse = await axios.post(tokenUrl, params);
2320
+ const token = tokenResponse.data.access_token;
2321
+
2322
+ // Get assistant
2323
+ const assistantUrl = `${CODEMIE_API_URL}/v1/assistants/id/${assistantId}`;
2324
+ const response = await axios.get(assistantUrl, {
2325
+ headers: { 'Authorization': `Bearer ${token}` },
2326
+ });
2327
+ ```
2328
+
2329
+ ### Mass Datasource Creation
2330
+
2331
+ When creating many datasources (30+), consider:
2332
+
2333
+ 1. **Generate from API data** - Use scripts to fetch existing datasources and generate config
2334
+ 2. **Use consistent naming** - Add suffix like `-copy` to avoid conflicts
2335
+ 3. **Validate repository URLs** - Ensure all Git URLs are accessible
2336
+ 4. **Monitor deployment** - Large datasource deployments can take 10+ minutes
2337
+
2338
+ ### Using Integration References
2339
+
2340
+ Integrations can be referenced in:
2341
+ - Datasource `setting_id`
2342
+ - Toolkit `settings`
2343
+ - Tool `settings` (within toolkit)
2344
+
2345
+ **Pattern:**
2346
+ ```yaml
2347
+ imported:
2348
+ integrations:
2349
+ - alias: my_integration
2350
+ id: uuid
2351
+ credential_type: Jira
2352
+
2353
+ # Reference in datasource
2354
+ resources:
2355
+ datasources:
2356
+ - setting_id: $ref:imported.integrations.my_integration.id
2357
+
2358
+ # Reference in assistant toolkit
2359
+ assistants:
2360
+ - toolkits:
2361
+ - toolkit: jira
2362
+ settings: $ref:imported.integrations.my_integration
2363
+ ```
2364
+
2365
+ ### Workflow Deployment Errors
2366
+
2367
+ **Error:** "Workflow assistant reference must have 'assistant_name'"
2368
+
2369
+ **Cause:** Workflow YAML has assistant without `assistant_name` field
2370
+
2371
+ **Fix:** Add `assistant_name` to reference existing assistant, or define inline assistant with `model` + `system_prompt` (which doesn't require `assistant_name`)
2372
+
2373
+ ---
2374
+
2375
+ **Error:** "Assistant 'X' not found in state or imported"
2376
+
2377
+ **Cause:** Referenced assistant doesn't exist yet
2378
+
2379
+ **Fix:**
2380
+ 1. Deploy assistant first, OR
2381
+ 2. Add to `imported.assistants` if it already exists on platform
2382
+
2383
+ ## Backup & Migration Notes
2384
+
2385
+ ### Field Compatibility
2386
+
2387
+ When creating backups or migrating between environments, the system automatically handles field name conversions between the platform API and IaC configuration format:
2388
+
2389
+ **Common conversions:**
2390
+ - API `llm_model_type` ↔ Config `model`
2391
+ - API `system_prompt` ↔ Config `prompt` (file path)
2392
+ - API `yaml_config` ↔ Config `definition` (file path)
2393
+
2394
+ **Datasource field conversions:**
2395
+ - API nested structure (e.g., `code.indexType`) ↔ Config flat structure (`index_type`)
2396
+ - Some fields use camelCase in API but snake_case in config for consistency
2397
+
2398
+ **What this means for you:**
2399
+ - ✅ Backups preserve all data correctly
2400
+ - ✅ Migration between environments works seamlessly
2401
+ - ✅ You don't need to manually convert field names
2402
+
2403
+ ## Architecture
2404
+
2405
+ ### SDK Integration Patterns
2406
+
2407
+ #### Pattern 1: API Field Transformations
2408
+
2409
+ Config field names are transformed to match SDK/API:
2410
+
2411
+ | Config Field | API Field | Notes |
2412
+ |-----------------------|------------------|--------------------------|
2413
+ | `model` | `llm_model_type` | LLM model name |
2414
+ | `link` | `link` | Git datasource URL |
2415
+ | `setting_id` | `setting_id` | Integration reference |
2416
+ | `jql` (top-level) | `jql` | Jira query |
2417
+ | `cql` (top-level) | `cql` | Confluence query |
2418
+
2419
+ **Note:** Datasource config uses flat structure. Nested `jira.jql` is legacy (auto-converted).
2420
+
2421
+ #### Pattern 2: Workflow Assistant Resolution
2422
+
2423
+ 1. Parse workflow YAML
2424
+ 2. For each `assistant_name`:
2425
+ - Lookup in `state.json` (IaC-created)
2426
+ - Fallback to `imported.assistants` (platform-existing)
2427
+ 3. Replace with `assistant_id` UUID
2428
+ 4. Send to API
2429
+
2430
+ ### Dependency Validation
2431
+
2432
+ **Cycle Detection:** DFS algorithm traverses sub-assistant graph, detects cycles
2433
+
2434
+ **Nested Sub-Assistant Detection:** Builds set of all assistants used as sub-assistants, checks if any have their own sub-assistants
2435
+
2436
+ ### Orphaned Resource Detection
2437
+
2438
+ 1. Load state.json resources: `{ assistants: { "A": {...}, "B": {...} } }`
2439
+ 2. Load config resources: `[ { name: "A" }, { name: "C" } ]`
2440
+ 3. Compare: B is in state but not in config → orphaned
2441
+ 4. Delete B from platform, remove from state
2442
+
2443
+
2444
+ ## Troubleshooting
2445
+
2446
+ ### "Environment variable not set" or "Connection failed"
2447
+
2448
+ **Cause:** Missing or incorrect environment variables
2449
+
2450
+ **Fix:**
2451
+ 1. Check that `.env` file exists in project root
2452
+ 2. Verify all required variables are set:
2453
+ ```bash
2454
+ cat .env # View your .env file
2455
+ ```
2456
+ 3. Ensure variable names match exactly (case-sensitive):
2457
+ - `CODEMIE_API_URL`
2458
+ - `CODEMIE_AUTH_URL`
2459
+ - `CODEMIE_REALM`
2460
+ - `CODEMIE_CLIENT_ID`
2461
+ - `CODEMIE_CLIENT_SECRET`
2462
+ 4. No quotes needed around values in `.env`
2463
+ 5. Restart your terminal/shell after creating `.env`
2464
+
2465
+ ### "Validation Error: Field required"
2466
+
2467
+ **Cause:** API expects field not provided in config
2468
+
2469
+ **Fix:** Check `examples/*.yaml` for required fields per resource type
2470
+
2471
+ ### "Assistant created but not found by name"
2472
+
2473
+ **Cause:** Multiple assistants with same name, or creation failed silently
2474
+
2475
+ **Fix:**
2476
+ 1. Check platform for duplicates
2477
+ 2. Use unique names
2478
+ 3. If SDK issue persists, contact support
2479
+
2480
+ ### "Datasource name cannot be changed"
2481
+
2482
+ **Platform limitation:** Datasource names are immutable after creation
2483
+
2484
+ **Workaround:**
2485
+ 1. Delete old datasource: Remove from config, deploy
2486
+ 2. Create new with desired name
2487
+
2488
+ ### "State.json out of sync"
2489
+
2490
+ **Symptoms:** Preview shows unexpected changes, or creates/deletes wrong resources
2491
+
2492
+ **Diagnosis:**
2493
+ ```bash
2494
+ # Check what's in state
2495
+ cat .codemie/state.json | jq '.resources'
2496
+
2497
+ # Check what's in config
2498
+ npm run validate
2499
+ ```
2500
+
2501
+ **Fix:** If state is wrong, restore from Git or manually reconstruct
2502
+
2503
+ ### "Checksum mismatch but no changes"
2504
+
2505
+ **Cause:** Line ending differences (CRLF vs LF), file encoding
2506
+
2507
+ **Fix:**
2508
+ 1. Normalize line endings: `git config core.autocrlf input`
2509
+ 2. Re-save prompt files with consistent encoding (UTF-8)
2510
+ 3. Redeploy to update checksums
2511
+
2512
+ ### "Workflow Configuration error"
2513
+
2514
+ **Cause:** Invalid workflow YAML structure or missing assistant references
2515
+
2516
+ **Common Issues:**
2517
+
2518
+ **1. Referenced assistant doesn't exist (404)**
2519
+ ```
2520
+ Error: Failed to deploy workflow: Assistant not found
2521
+ ```
2522
+
2523
+ **Solution:**
2524
+ - Verify assistant exists on platform
2525
+ - Add to `imported.assistants` if it's platform-managed
2526
+ - Ensure assistant is deployed first if it's IaC-managed
2527
+
2528
+ ```yaml
2529
+ # Add to codemie.yaml
2530
+ imported:
2531
+ assistants:
2532
+ - id: 79db7d36-eb89-468d-a99f-44fd4bf92b01
2533
+ name: Exact Assistant Name # Must match platform exactly
2534
+ ```
2535
+
2536
+ **2. Invalid retry_policy fields**
2537
+ ```
2538
+ Error: Workflow Configuration error
2539
+ ```
2540
+
2541
+ **Solution:**
2542
+ Use correct field names in workflow YAML:
2543
+ ```yaml
2544
+ # ❌ Wrong
2545
+ retry_policy:
2546
+ initial_interval_seconds: 1
2547
+ max_interval_seconds: 10
2548
+
2549
+ # ✅ Correct
2550
+ retry_policy:
2551
+ initial_interval: 1
2552
+ max_interval: 10
2553
+ ```
2554
+
2555
+ **3. Mixed assistant reference types**
2556
+ ```
2557
+ Error: Workflow assistant must have either assistant_name or model
2558
+ ```
2559
+
2560
+ **Solution:**
2561
+ Don't mix `assistant_name` with `model`/`system_prompt`:
2562
+ ```yaml
2563
+ assistants:
2564
+ # ❌ Wrong - mixing external reference with inline definition
2565
+ - id: step1
2566
+ assistant_name: My Assistant
2567
+ model: gpt-4o # Remove this!
2568
+
2569
+ # ✅ Correct - external reference
2570
+ - id: step1
2571
+ assistant_name: My Assistant
2572
+
2573
+ # ✅ Correct - inline definition
2574
+ - id: step2
2575
+ model: gpt-4o-mini
2576
+ name: Parser
2577
+ system_prompt: "You are a parser..."
2578
+ ```
2579
+
2580
+ ### "Assistant 'X' not found in state or imported"
2581
+
2582
+ **Cause:** Workflow references assistant that doesn't exist in IaC configuration
2583
+
2584
+ **Solution:**
2585
+
2586
+ **Option 1: Import the assistant**
2587
+ ```yaml
2588
+ # codemie.yaml
2589
+ imported:
2590
+ assistants:
2591
+ - id: uuid-from-platform # Get from Codemie UI → Assistants → Copy ID
2592
+ name: Exact Assistant Name # Case-sensitive!
2593
+ ```
2594
+
2595
+ **Option 2: Deploy assistant first**
2596
+ ```yaml
2597
+ # codemie.yaml
2598
+ resources:
2599
+ assistants:
2600
+ - name: My Assistant # Must match workflow reference exactly
2601
+ prompt: ./system_prompts/assistant.prompt.md
2602
+ model: gpt-4o
2603
+ ```
2604
+
2605
+ **Verification:**
2606
+ ```bash
2607
+ # Check configuration
2608
+ npm run validate
2609
+
2610
+ # Verify assistant name matches
2611
+ grep -A 2 "assistant_name:" workflows/*.yaml
2612
+ grep "name:" codemie.yaml
2613
+ ```
2614
+
2615
+ ## CI/CD Integration
2616
+
2617
+ Example GitLab CI/CD pipeline:
2618
+
2619
+ ```yaml
2620
+ stages:
2621
+ - validate
2622
+ - preview
2623
+ - deploy
2624
+
2625
+ # Basic validation (feature branches, MRs) - fast, no API connection
2626
+ validate:basic:
2627
+ stage: validate
2628
+ script:
2629
+ - npm install
2630
+ - npm run validate:basic
2631
+ rules:
2632
+ - if: '$CI_COMMIT_REF_NAME == "master"'
2633
+ when: never
2634
+ - when: always
2635
+
2636
+ # Full validation (master branch) - includes API connectivity check
2637
+ validate:full:
2638
+ stage: validate
2639
+ script:
2640
+ - npm install
2641
+ - npm run validate
2642
+ rules:
2643
+ - if: '$CI_COMMIT_REF_NAME == "master"'
2644
+ when: always
2645
+ - when: never
2646
+
2647
+ preview:
2648
+ stage: preview
2649
+ script:
2650
+ - npm install
2651
+ - npm run preview
2652
+ rules:
2653
+ - if: '$CI_COMMIT_REF_NAME == "master"'
2654
+ changes:
2655
+ - codemie.yaml # Main IaC configuration
2656
+ - system_prompts/**/* # Assistant prompts
2657
+ - workflows/**/* # Workflow definitions
2658
+ when: always
2659
+
2660
+ deploy:
2661
+ stage: deploy
2662
+ resource_group: production # Sequential execution
2663
+ script:
2664
+ - npm install
2665
+ - npm run deploy -- --prune
2666
+ after_script:
2667
+ - |
2668
+ if [ -n "$(git status --porcelain .codemie/state.json)" ]; then
2669
+ git config user.name "GitLab CI"
2670
+ git config user.email "ci@gitlab.com"
2671
+ git add .codemie/state.json
2672
+ git commit -m "chore: Update IaC state [skip ci]"
2673
+ git push https://gitlab-ci-token:${RUNNER_CLONE_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git HEAD:${CI_COMMIT_REF_NAME}
2674
+ fi
2675
+ rules:
2676
+ - if: '$CI_COMMIT_REF_NAME == "master"'
2677
+ changes:
2678
+ - codemie.yaml # Main IaC configuration
2679
+ - system_prompts/**/* # Assistant prompts
2680
+ - workflows/**/* # Workflow definitions
2681
+ when: manual
2682
+ ```
2683
+
2684
+ **Key points:**
2685
+ - **Two-tier validation:**
2686
+ - `validate:basic` runs for feature branches (fast, no credentials needed)
2687
+ - `validate:full` runs for master after merge (full API checks)
2688
+ - `resource_group: production` ensures sequential deploys (no state conflicts)
2689
+ - `after_script` commits updated state.json back to repo
2690
+ - `[skip ci]` prevents infinite pipeline loop
2691
+ - `changes:` triggers deploy only for resource configuration files (not for IaC tool code in `src/`)
2692
+
2693
+ ## Team Collaboration
2694
+
2695
+ ### Git Workflow for IaC Changes
2696
+
2697
+ **1. Create Feature Branch**
2698
+ ```bash
2699
+ git checkout -b feature/update-assistant-prompt
2700
+ ```
2701
+
2702
+ **2. Make Changes**
2703
+ - Edit prompts in `system_prompts/`
2704
+ - Update configuration in `codemie.yaml`
2705
+ - Add new workflows in `workflows/`
2706
+
2707
+ **3. Test Locally**
2708
+ ```bash
2709
+ npm run validate:basic # Quick syntax check (no API connection)
2710
+ npm run validate # Full validation with API checks (optional)
2711
+ npm run preview # Preview changes
2712
+ ```
2713
+
2714
+ **4. Create Pull Request**
2715
+
2716
+ **What happens in CI (for feature branches):**
2717
+ - ✅ **Validate stage** - Basic validation (YAML syntax, file existence, dependencies) - no API connection required
2718
+ - ✅ **Preview stage** - Shows deployment preview in MR comments
2719
+
2720
+ **5. Review Process**
2721
+ - Team reviews prompt changes
2722
+ - Verify deployment preview looks correct
2723
+ - Check that no unintended resources will be deleted
2724
+ - Approve MR
2725
+
2726
+ **6. Merge to Main**
2727
+
2728
+ **What happens after merge to master:**
2729
+ - ✅ Full validation runs (with API connectivity check)
2730
+ - ✅ GitLab CI automatically deploys changes
2731
+ - ✅ State.json is updated and committed back
2732
+ - ✅ All changes are live on Codemie platform
2733
+
2734
+ ### Best Practices for Team Collaboration
2735
+
2736
+ **1. Commit state.json to Git**
2737
+ - Essential for team to see current deployment state
2738
+ - Enables accurate deployment previews
2739
+ - Provides audit trail
2740
+
2741
+ **2. Use descriptive branch names**
2742
+ ```bash
2743
+ # Good
2744
+ feature/add-code-review-assistant
2745
+ fix/update-jira-datasource-query
2746
+ chore/update-all-assistant-models
2747
+
2748
+ # Not helpful
2749
+ feature/changes
2750
+ fix/update
2751
+ ```
2752
+
2753
+ **3. Small, focused changes**
2754
+ - One assistant per MR
2755
+ - Related changes together (assistant + datasource)
2756
+ - Easier to review and rollback
2757
+
2758
+ **4. Review deployment preview**
2759
+ - Always check `preview` output before merging
2760
+ - Watch for unexpected deletions
2761
+ - Verify resource counts
2762
+
2763
+ **5. Sequential deployments**
2764
+ - GitLab `resource_group: production` ensures one deploy at a time
2765
+ - No state conflicts
2766
+ - No race conditions
2767
+
2768
+ **6. Document breaking changes**
2769
+ - Renaming assistants breaks references
2770
+ - Workflow changes may affect users
2771
+ - Note in MR description
2772
+
2773
+ ### Handling State Conflicts
2774
+
2775
+ **Scenario:** Two team members work on different features simultaneously
2776
+
2777
+ **Branch A:** Adds Assistant 1
2778
+ **Branch B:** Adds Assistant 2
2779
+
2780
+ **What happens:**
2781
+ 1. Branch A merges first → state.json updated with Assistant 1
2782
+ 2. Branch B tries to merge → **Git conflict in state.json**
2783
+ 3. Manual resolution needed:
2784
+ ```json
2785
+ {
2786
+ "assistants": {
2787
+ "Assistant 1": { "id": "uuid-1", ... },
2788
+ "Assistant 2": { "id": "uuid-2", ... } // Keep both!
2789
+ }
2790
+ }
2791
+ ```
2792
+ 4. After resolving, run `npm run deploy` to verify
2793
+
2794
+ **Prevention:**
2795
+ - Keep feature branches short-lived
2796
+ - Sync with main frequently
2797
+ - Use `resource_group` in CI/CD (enforces sequential execution)
2798
+
2799
+ ## Development
2800
+
2801
+ ### Architecture & Code Organization
2802
+
2803
+ This project follows clean separation between business logic and CLI execution:
2804
+
2805
+ **Core Logic (`src/`)** - All main functionality is implemented in testable modules:
2806
+ - `deploy.ts` - Deployment logic (creates/updates resources)
2807
+ - `backup.ts` - Backup logic (downloads all resources)
2808
+ - `destroy.ts` - Destroy logic (deletes all managed resources)
2809
+ - `preview.ts` - Preview logic (shows what will change)
2810
+ - `validate.ts` - Validation logic (checks configuration correctness)
2811
+
2812
+ Each module exports a `main()` function containing the full business logic. These functions are pure and testable - they don't execute automatically on import.
2813
+
2814
+ **CLI Entry Point (`src/cli/`)** - Unified router for all commands:
2815
+ - `index.ts` - Routes commands to appropriate handlers with type-safe command registry
2816
+
2817
+ These files are the only ones that call `process.exit()` and contain shebangs.
2818
+
2819
+ **Library Code (`src/lib/`)** - Reusable utility modules with high test coverage (>89%):
2820
+ - Configuration loading, state management, API clients
2821
+ - Resource converters, validators, dependency resolution
2822
+ - Retry logic, rate limiting, transaction management
2823
+
2824
+ **Testing Strategy:**
2825
+ - All library code in `src/lib/` has extensive unit test coverage
2826
+ - Core logic modules export their functions for testing
2827
+ - Tests can import and test individual functions without triggering CLI execution
2828
+ - CLI entry points are thin and don't need unit tests
2829
+ - Coverage metrics (89%+) reflect actual code quality
2830
+
2831
+ **Benefits:**
2832
+ - ✅ Testability: All business logic can be imported and tested without side effects
2833
+ - ✅ Reusability: Core functions can be imported by other Node.js projects
2834
+ - ✅ Maintainability: Clear separation between CLI concerns and business logic
2835
+ - ✅ Linting: ESLint rule "no-process-exit" only applies to library code, not CLI wrappers
2836
+
2837
+ ```bash
2838
+ # Build TypeScript
2839
+ npm run build
2840
+
2841
+ # Type checking
2842
+ npm run type-check
2843
+
2844
+ # Clean build artifacts
2845
+ npm run clean
2846
+
2847
+ # Run tests
2848
+ npm test
2849
+
2850
+ # Run tests with coverage
2851
+ npm test -- --coverage
2852
+ ```
2853
+
2854
+ ## License
2855
+
2856
+ Copyright © 2025 EPAM Systems, Inc.