@cmflow/agents 3.4.0-alpha.1 → 3.4.0-beta.32

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 CHANGED
@@ -1,403 +1,225 @@
1
- <div style="text-align: center" align="center">
2
- <img src="https://ns.clubmed.com/fbs/RWD/branding2023/Logo/MicrosoftTeams-image%20(9).png" width="200" alt="Club Med"/>
3
- </div>
1
+ # @cmflow/agents
4
2
 
5
- <div align="center">
6
- <h1>@cmflow/atlas</h1>
7
- <hr />
3
+ CLI for installing and configuring AI tools for Club Med developers (Codex, Claude, MCPs).
8
4
 
9
- [![npm version](https://badge.fury.io/js/%40cmflow%2Fatlas.svg)](https://badge.fury.io/js/%40cmflow%2Fatlas)
10
- [![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
11
- [![code style: oxfmt](https://img.shields.io/badge/code_style-oxfmt-ef4444.svg?style=flat-square)](https://oxc.rs/docs/guide/usage/formatter)
5
+ ## Quick start
12
6
 
13
- </div>
14
-
15
- Atlas builds an API-to-backend mapping catalogue from an OpenAPI contract and static TypeScript analysis. It generates a reviewable YAML document per route, can optionally infer unresolved mappings, and synchronizes confirmed mappings with Directus.
16
-
17
- ## What Atlas produces
18
-
19
- For each API route, Atlas writes a route-centric YAML document and a companion `.graph.yaml` file. The graph records the resolved path from the API handler to its backends; the YAML records inputs, outputs, mapping evidence and fields that require review.
20
-
21
- ## Install
22
-
23
- ```bash
24
- npm install --save-dev @cmflow/atlas
25
- ```
7
+ ### macOS / Linux
26
8
 
27
9
  ```bash
28
- yarn add -D @cmflow/atlas
29
- ```
10
+ # 1. Install mise
11
+ curl https://mise.run | sh
30
12
 
31
- ```bash
32
- pnpm add -D @cmflow/atlas
33
- ```
13
+ # 2. Activate mise in the current shell
14
+ eval "$(~/.local/bin/mise activate bash)" # or: zsh
34
15
 
35
- ## Initialize a target API project
16
+ # 3. Install Node.js 24
17
+ mise use -g node@24
36
18
 
37
- Create `atlas.config.ts` at the root of the API project; it does not belong in the Atlas package.
38
-
39
- ```bash
40
- atlas init
41
- # or create it at an explicit location
42
- atlas --config /path/to/api/atlas.config.ts init
19
+ # 4. Run the Club Med setup
20
+ npx -p @cmflow/agents cm-agents install
43
21
  ```
44
22
 
45
- By default, Atlas loads `atlas.config.ts` from the directory where the command is launched. Use `--config` (or `-c`) to reference another configuration file. Use `--analysis-dir` only to override the API source directory to analyze.
46
-
47
- The configuration imports `defineConfig` from Atlas:
48
-
49
- ```ts
50
- import { defineConfig } from "@cmflow/atlas";
51
-
52
- export default defineConfig({
53
- outputDir: "./tmp/atlas",
54
- envs: {
55
- XM_API_URL: "https://xm.example/openapi.json"
56
- },
57
- openapiUrl: "https://api.example.com/openapi.json",
58
- openapiTimeoutMs: 60_000,
59
- directusUrl: "https://cms.api.clubmed",
60
- analysis: {
61
- rootDir: "./app",
62
- backends: ["ICC", "CMS", "CMS_B2C"]
63
- }
64
- });
65
- ```
23
+ ### Windows (PowerShell, no admin rights required)
66
24
 
67
- `process.cwd()` is always the project root: `outputDir`, `tsconfig.json`, Git paths and serialized source paths are resolved from it. `analysis.rootDir` only defines the source tree to analyze and may therefore point to a subdirectory such as `./app`. Atlas reads `compilerOptions.paths` from the root `tsconfig.json` and uses them as module aliases. Add `resolver.alias` only to override or complement those aliases.
25
+ ```powershell
26
+ # 1. Install mise via winget
27
+ winget install --id jdx.mise --accept-source-agreements --accept-package-agreements --silent
68
28
 
69
- `outputDir` is resolved from the project root, not from `analysis.rootDir`. With the configuration above, artifacts are written to `<project-root>/tmp/atlas`, never to `<project-root>/app/tmp/atlas`.
29
+ # 2. Activate mise in PowerShell
30
+ (&mise activate pwsh) | Out-String | Invoke-Expression
70
31
 
71
- Use `analysis.excluded` for project-root-relative technical files that must not enter dependency traversal or `analysis_files`:
32
+ # 3. Install Node.js 24
33
+ mise use -g node@24
72
34
 
73
- ```ts
74
- analysis: {
75
- rootDir: "./app",
76
- excluded: ["tools/build/*-reference.json"],
77
- backends: [/* ... */]
78
- }
35
+ # 4. Run the Club Med setup
36
+ npx -p @cmflow/agents cm-agents install
79
37
  ```
80
38
 
81
- ## Backend sources
82
-
83
- Atlas starts from accesses actually detected in code on a backend reached by the route graph. It then consolidates those code candidates against the canonical properties returned by the matching `BackendSource`. Atlas never creates a confirmed mapping from API field-name similarity alone.
39
+ ## Commands
84
40
 
85
- For a backend with no configured source, Atlas preserves code candidates for optional AI inference. A configured source is authoritative: only its resolved properties can validate the code access.
41
+ ### `cm-agents install [--reinstall]`
86
42
 
87
- A backend can be either a string or a `BackendSource` created with `defineBackendSource`:
43
+ Interactive full workstation setup:
88
44
 
89
- - a string (for example `"ICC"`) has no field reference; Atlas keeps the current code-analysis and optional inference flow;
90
- - a `BackendSource` provides a `resolve` function that returns the backend's known properties. Atlas assigns its `name` as `backend` on every resolved property.
45
+ 1. Checks Git is available
46
+ 2. Collects secrets and preferences via interactive prompts:
47
+ - `LITELLM_API_KEY`, `ANTHROPIC_API_KEY`, MCP keys…
48
+ - **"Configure Codex with Club Med LiteLLM?"** — yes fetches the model catalog and writes the LiteLLM provider config; no keeps the personal OpenAI account untouched
49
+ 3. Clones / updates the `digital-api-team-skills` repository
50
+ 4. Writes environment variables to the shell rc (Unix) or user scope (Windows)
51
+ 5. Installs and configures **Codex CLI** (MCPs; LiteLLM config if chosen)
52
+ 6. Installs and configures **Claude CLI** (HTTP MCPs, Atlassian marketplace plugin)
53
+ 7. Optionally installs Python 3.12 via mise
91
54
 
92
- Any backend source can persist its resolved properties in a YAML cache. When the cache exists, Atlas uses it and does not call the remote source. Refresh it explicitly with `atlas backend-source --refresh` (or the compatible `atlas backend-sources --refresh`). Use `atlas backend-sources --refresh --all` to refresh every configured source without an interactive prompt.
93
-
94
- ```ts
95
- export const xm = defineBackendSource({
96
- name: "XM",
97
- cache: `${__dirname}/cache.yaml`,
98
- resolve: () => openapiSource({ url: "https://xm.example/openapi.json" })
99
- });
55
+ ```bash
56
+ npx -p @cmflow/agents cm-agents install
57
+ npx -p @cmflow/agents cm-agents install --reinstall # force reinstall of every tool
100
58
  ```
101
59
 
102
- When a string and a source share the same name, the last declaration wins. This lets a source enrich a list of backend names, for example `[..., Object.values(BackendTypes), quableBackendSource]`.
103
-
104
- The resolver returns one of the following shapes. Document-oriented backends have no route; REST backends have no document.
105
-
106
- ```ts
107
- type BackendProperty =
108
- | {
109
- document: string;
110
- field: string;
111
- description?: string;
112
- }
113
- | {
114
- route: string;
115
- method: string;
116
- field: string;
117
- description?: string;
118
- };
119
- ```
60
+ ### `cm-agents check`
120
61
 
121
- The generated mapping preserves this shape. In particular, `document` is a separate property: Atlas does not turn a Quable field into an artificial path such as `products.product_geographical_area`.
62
+ Checks the workstation installation state and prints a pass / warn / fail report:
122
63
 
123
- ## Resolved backend metadata artifacts
64
+ - **Node.js version** 20 (via `process.version`)
65
+ - **git**, **codex**, **claude** present in PATH
66
+ - **python** present in PATH (optional — warn only)
67
+ - Required environment variables
68
+ - Codex config (`~/.codex/config.toml` + standard MCPs)
69
+ - **Codex LiteLLM provider**: `model_provider = "litellm"`, correct `base_url`, `model_catalog_json` exists, active `model` is in the catalog
70
+ - **Kibana MCPs**: warns if no `kibana_*` profile is configured in Codex
71
+ - Claude MCPs configured
72
+ - Repository cloned
124
73
 
125
- At the start of `generate:graph` and `generate:catalog`, Atlas resolves every configured backend source and writes its metadata for inspection:
74
+ > `mise` and `node` are not checked for presence they are prerequisites to run this CLI at all.
126
75
 
127
- ```text
128
- <outputDir>/backends/<backend>.yaml
76
+ ```bash
77
+ npx -p @cmflow/agents cm-agents check
129
78
  ```
130
79
 
131
- For example, `<outputDir>/backends/quable_rest.yaml` contains the source name, generation date and canonical properties returned by Quable. Backends declared as strings still receive an artifact with `resolved: false`; this makes missing metadata sources visible during analysis.
80
+ ### `cm-agents codex use openai [--model <model>]`
132
81
 
133
- ### Quable
82
+ Switches Codex back to the personal OpenAI account:
83
+ - Removes `model_provider`, `model_catalog_json`, `model_providers`, `openai_base_url`
84
+ - Lists available models via the OpenAI SDK (`openai.models.list()`) and shows an interactive select prompt
85
+ - Falls back to `gpt-5.6-luna` if `OPENAI_API_KEY` is not set or the API is unreachable
134
86
 
135
- Attach rules that are specific to Quable directly to its source. They inherit the source backend automatically and their candidates are validated by the Quable property list.
136
-
137
- ```ts
138
- import { defineBackendSource, httpClient } from "@cmflow/atlas";
139
- import { quableI18nFieldRule } from "./atlas-rules";
140
-
141
- export const quable = defineBackendSource({
142
- name: "QUABLE",
143
- rules: [quableI18nFieldRule],
144
- resolve: async () => {
145
- const documentTypes = await httpClient.get<QuableDocumentType[]>("https://quable.example/document-types");
146
-
147
- return documentTypes.flatMap((document) =>
148
- document.properties.map((property) => ({
149
- document: document.code,
150
- field: property.code,
151
- description: "récupéré via le backend resolver"
152
- }))
153
- );
154
- }
155
- });
87
+ ```bash
88
+ cm-agents codex use openai # interactive model selection
89
+ cm-agents codex use openai --model gpt-5.6-luna # skip selection
156
90
  ```
157
91
 
158
- For example, the resolver above may return:
92
+ ### `cm-agents codex use litellm`
159
93
 
160
- ```ts
161
- {
162
- backend: "QUABLE",
163
- document: "products",
164
- field: "product_geographical_area",
165
- description: "récupéré via le backend resolver"
166
- }
167
- ```
94
+ Switches Codex to the Club Med LiteLLM provider:
95
+ - If `model_providers.litellm` is not yet configured, prompts for `LITELLM_API_KEY` and `base_url` (default: `https://litellm-aiplatform.ai.clubmed.com`)
96
+ - Fetches the Club Med model catalog from the LiteLLM API → writes `~/.codex/clubmed-models.json`
97
+ - Sets `model_provider = "litellm"`, `model_catalog_json`, and `model_providers.litellm`
168
98
 
169
- ### CMS Directus
99
+ ```bash
100
+ cm-agents codex use litellm
101
+ ```
170
102
 
171
- CMS Directus follows the same document-oriented contract. Its `cmsI18nFieldRule` is owned by the CMS source rather than registered as a global expression rule.
103
+ Expected result in `~/.codex/config.toml`:
172
104
 
173
- ```ts
174
- import { defineBackendSource } from "@cmflow/atlas";
175
- import { cmsI18nFieldRule } from "./atlas-rules";
105
+ ```toml
106
+ model = "<default-model-from-catalog>"
107
+ model_provider = "litellm"
108
+ model_catalog_json = "~/.codex/clubmed-models.json"
176
109
 
177
- export const cmsDirectus = defineBackendSource({
178
- name: "CMS",
179
- rules: [cmsI18nFieldRule],
180
- resolve: async () => directusResolver.listProperties()
181
- });
110
+ [model_providers.litellm]
111
+ name = "LiteLLM"
112
+ base_url = "<litellm-base-url>"
113
+ env_key = "LITELLM_API_KEY"
114
+ wire_api = "responses"
182
115
  ```
183
116
 
184
- `directusResolver.listProperties()` returns items such as `{ document: "offers", field: "title", description: "…" }`.
117
+ ### `cm-agents codex models`
185
118
 
186
- ### CMS Legacy
119
+ Displays the active Codex configuration and the list of models available in the local catalog.
187
120
 
188
- CMS Legacy is configured identically, with its own resolver and backend identifier. It may reuse `cmsI18nFieldRule` when the backend uses `CmsI18n` helpers.
189
-
190
- ```ts
191
- import { defineBackendSource } from "@cmflow/atlas";
192
- import { cmsI18nFieldRule } from "./atlas-rules";
193
-
194
- export const cmsLegacy = defineBackendSource({
195
- name: "CMS_LEGACY",
196
- rules: [cmsI18nFieldRule],
197
- resolve: async () => cmsLegacyResolver.listProperties()
198
- });
121
+ ```bash
122
+ cm-agents codex models
199
123
  ```
200
124
 
201
- ### Custom REST backend with OpenAPI
125
+ ### `cm-agents codex models --refresh`
202
126
 
203
- `openapiSource` reuses Atlas's OpenAPI parsing utilities: downloading the document, resolving references, traversing operations, and extracting field descriptions. A project therefore only supplies the URL.
127
+ Refreshes `~/.codex/clubmed-models.json` by querying the LiteLLM API.
128
+ Requires `LITELLM_API_KEY` to be set in the environment.
204
129
 
205
- ```ts
206
- import { constant, defineBackendSource, openapiSource } from "@cmflow/atlas";
207
-
208
- export const xm = defineBackendSource({
209
- name: "XM",
210
- cache: `${__dirname}/xm-openapi.yaml`,
211
- resolve: () =>
212
- openapiSource({
213
- url: constant<string>("XM_API_URL", "https://xm.example/openapi.json")
214
- })
215
- });
130
+ ```bash
131
+ cm-agents codex models --refresh
216
132
  ```
217
133
 
218
- `constant` resolves a value declared in `envs`, falling back to its second argument. No resolver context is required.
134
+ ### `cm-agents kibana setup <profile>`
219
135
 
220
- ### Environment constants
136
+ Runs the interactive Kibana MCP profile setup wizard for the given profile name (`prod`, `staging`, or any custom name).
221
137
 
222
- Use `constant` when a backend source needs a configurable value such as a URL or an access token. Declare injected values at the root of `atlas.config.ts`; the value is resolved when the source runs:
138
+ - Streams `npx @havesomecode/kibana-mcp-server setup` with full stdin/stdout relay.
139
+ - After a successful setup, registers `kibana_<profile>` as a **stdio MCP** in both Codex and Claude.
223
140
 
224
- 1. Atlas uses `envs[name]` when it is set.
225
- 2. Otherwise, it returns the supplied default value.
226
-
227
- ```ts
228
- import { constant, defineBackendSource, openapiSource } from "@cmflow/atlas";
229
-
230
- export const xmBackendSource = defineBackendSource({
231
- name: "XM",
232
- resolve: () =>
233
- openapiSource({
234
- url: constant<string>("XM_API_URL", "https://xm.example/openapi.json")
235
- })
236
- });
141
+ ```bash
142
+ cm-agents kibana setup prod
143
+ cm-agents kibana setup staging
144
+ cm-agents kibana setup prod --reinstall # re-register even if already present
237
145
  ```
238
146
 
239
- For example, configure the endpoint used by the source:
147
+ Once a profile is configured, the MCP server is started on demand:
240
148
 
241
- ```ts
242
- export default defineConfig({
243
- envs: {
244
- XM_API_URL: "https://xm.internal/openapi.json"
245
- }
246
- // …other Atlas options
247
- });
149
+ ```bash
150
+ KIBANA_PROFILE=prod npx -y @havesomecode/kibana-mcp-server serve
151
+ KIBANA_PROFILE=staging npx -y @havesomecode/kibana-mcp-server serve
248
152
  ```
249
153
 
250
- `envs` can itself be populated from `process.env` when appropriate for the project.
154
+ The registered MCP JSON (used for both Codex and Claude):
251
155
 
252
- This returns entries such as:
253
-
254
- ```ts
156
+ ```json
255
157
  {
256
- backend: "XM",
257
- route: "/path/to",
258
- method: "GET",
259
- field: "path.to.field",
260
- description: "Description extraite du Swagger"
158
+ "type": "stdio",
159
+ "command": "npx",
160
+ "args": ["-y", "@havesomecode/kibana-mcp-server", "serve"],
161
+ "env": { "KIBANA_PROFILE": "prod" }
261
162
  }
262
163
  ```
263
164
 
264
- Register strings and sources together:
265
-
266
- ```ts
267
- import { defineConfig } from "@cmflow/atlas";
268
- import { cmsDirectus, cmsLegacy, quable, xm } from "./backend-sources";
269
-
270
- export default defineConfig({
271
- // …other Atlas options
272
- analysis: {
273
- backends: ["ICC", quable, cmsDirectus, cmsLegacy, xm]
274
- }
275
- });
276
- ```
277
-
278
- ## Custom expression rules
279
-
280
- Use `defineExpressionRule` when a project-specific helper hides a backend field or wraps an expression that Atlas should follow. Define those rules in the analyzed project, add a cross-backend rule to `analysis.rules` in `atlas.config.ts`, and attach backend-specific rules to `defineBackendSource({ rules: [...] })` instead.
281
-
282
- `match` is a cheap predicate that selects the `ts-morph` expression. `parse` returns the information Atlas should use: a backend field, a transparent wrapper, or both.
283
-
284
- ```ts
285
- import { defineConfig, defineExpressionRule } from "@cmflow/atlas";
286
- import { Node } from "ts-morph";
287
-
288
- const localizedFieldRule = defineExpressionRule({
289
- name: "localized-field",
290
- match: (expression) => Node.isCallExpression(expression) && expression.getExpression().getText() === "localizedField",
291
- parse: (expression) => {
292
- if (!Node.isCallExpression(expression)) return undefined;
293
-
294
- const [source, field] = expression.getArguments();
295
- if (!source || !Node.isExpression(source) || !Node.isStringLiteral(field)) return undefined;
296
-
297
- return { backendField: `${source.getText()}.${field.getLiteralValue()}` };
298
- }
299
- });
300
-
301
- export default defineConfig({
302
- // …other Atlas options
303
- analysis: {
304
- // …other analysis options
305
- rules: [localizedFieldRule]
306
- }
307
- });
308
- ```
309
-
310
- For a wrapper that does not change the field path, return `transparent: true`:
311
-
312
- ```ts
313
- const unwrapRule = defineExpressionRule({
314
- name: "unwrap-api-value",
315
- match: (expression) => Node.isCallExpression(expression) && expression.getExpression().getText() === "unwrap",
316
- parse: () => ({ transparent: true })
317
- });
318
- ```
319
-
320
- `parse` may also set `mapperType` to annotate the generated mapping, or `apiMapping: true` when the helper maps an API value rather than a backend value.
321
-
322
- Create a `.env.local` in the target API project when pushing to Directus:
323
-
324
- ```dotenv
325
- DIRECTUS_URL=https://****
326
- DIRECTUS_TOKEN=replace-with-a-static-token
327
- ```
328
-
329
- ## Workflow
165
+ ### `cm-agents kibana serve <profile>`
330
166
 
331
- Generate the topology first, then the route catalogue:
167
+ Starts the Kibana MCP server for a given profile — a thin proxy for:
332
168
 
333
169
  ```bash
334
- atlas --analysis-dir /path/to/api generate:graph
335
- atlas --analysis-dir /path/to/api generate:catalog --output .tmp/datasource-catalogue
170
+ KIBANA_PROFILE=<profile> npx -y @havesomecode/kibana-mcp-server serve
336
171
  ```
337
172
 
338
- Each route produces a YAML document and a `.graph.yaml` topology artifact. The catalogue requires a valid graph and leaves ambiguous fields marked `needs_review`.
339
-
340
- When changing `analysis.rootDir`, backend sources or exclusions, regenerate the graph before the catalogue so the route graph and metadata artifacts use the same configuration:
341
-
342
- ```bash
343
- atlas generate:graph "GET /v2/products"
344
- atlas generate:catalog "GET /v2/products"
345
- ```
346
-
347
- Check configured coverage baselines:
348
-
349
173
  ```bash
350
- atlas --analysis-dir /path/to/api generate:test
174
+ cm-agents kibana serve prod
175
+ cm-agents kibana serve staging
351
176
  ```
352
177
 
353
- Review unresolved mappings or run optional AI inference:
178
+ ## Environment variables
354
179
 
355
- ```bash
356
- atlas --analysis-dir /path/to/api needs-review --sort percentage --limit 25
357
- atlas --analysis-dir /path/to/api infer .tmp/datasource-catalogue
358
- ```
180
+ | Variable | Purpose |
181
+ |----------------------------------|--------------------------------------------------|
182
+ | `LITELLM_API_KEY` | LiteLLM key (AI portal — VPN required) |
183
+ | `ANTHROPIC_API_KEY` | Anthropic key (same portal) |
184
+ | `ANTHROPIC_BASE_URL` | LiteLLM proxy base URL |
185
+ | `ANTHROPIC_DEFAULT_SONNET_MODEL` | Default Claude model |
186
+ | `ANTHROPIC_DEFAULT_FABLE_MODEL` | Fable model |
187
+ | `ANTHROPIC_DEFAULT_OPUS_MODEL` | Opus model |
188
+ | `ANTHROPIC_DEFAULT_HAIKU_MODEL` | Haiku model |
189
+ | `CLUBMED_API_MCP_KEY` | Club Med API portal MCP key |
190
+ | `CMS_API_MCP_TOKEN` | CMS Directus MCP token (optional) |
191
+ | `CLUBMED_REPO_DIR` | Path to the `digital-api-team-skills` repository |
359
192
 
360
- The inference pass only reads analysis files referenced by each route graph. Accepted suggestions remain marked `inferred`; suggestions below the configured confidence threshold are retained for manual review.
193
+ ## Configured MCPs
361
194
 
362
- Push route artifacts to Directus with an explicit write flag:
195
+ ### Codex (`~/.codex/config.toml`)
363
196
 
364
- ```bash
365
- atlas --analysis-dir /path/to/api push .tmp/datasource-catalogue --update
366
- ```
197
+ | Name | URL |
198
+ |---------------|-------------------------------------------|
199
+ | `clubmed_api` | `https://portal.api.clubmed/mcp` |
200
+ | `cms_api` | `https://cms.api.clubmed/mcp` |
201
+ | `atlassian` | `https://mcp.atlassian.com/v1/mcp/authv2` |
367
202
 
368
- Without `--update`, the command performs a dry run. Use `clean-orphans` to inspect Directus links that no longer reference an API or backend property.
369
-
370
- ## Command reference
371
-
372
- ```text
373
- atlas init Create atlas.config.ts
374
- atlas backend-source [--refresh] Display backend metadata; refresh configured source caches when requested
375
- atlas backend-sources [--refresh] [--all] Compatible plural alias; --all skips the source picker
376
- atlas generate:graph Trace API routes to backends
377
- atlas generate:catalog [route] Generate route review documents
378
- atlas generate:test Check configured coverage baselines
379
- atlas needs-review Rank unresolved routes
380
- atlas infer [route|directory] Optionally enrich unresolved mappings
381
- atlas push [directory|route] Preview or push mappings to Directus
382
- atlas clean-orphans Inspect or delete orphaned Directus links
383
- atlas report:changed Report coverage for changed routes
384
- ```
203
+ ### Claude (user scope)
385
204
 
386
- ## CI
205
+ | Name | URL |
206
+ |---------------|--------------------------------------------------------|
207
+ | `clubmed_api` | `https://portal.api.clubmed/mcp` |
208
+ | `cms_api` | `https://cms.api.clubmed/mcp` |
209
+ | `atlassian` | Marketplace plugin `atlassian@claude-plugins-official` |
387
210
 
388
- The recommended static CI flow is `generate:graph`, `generate:catalog`, then `push`. Do not run optional inference in CI. Supply `DIRECTUS_URL` and `DIRECTUS_TOKEN` through the CI secret context; skip the push if either value is absent.
211
+ ## Post-install manual steps
389
212
 
390
- ## Development
213
+ 1. Restart the terminal to load environment variables
214
+ 2. Authenticate Atlassian for Codex: `codex mcp login atlassian`
215
+ 3. Install the ChatGPT app (Codex UI): <https://chatgpt.com/download>
216
+ 4. Install Claude Desktop: <https://claude.ai/download>
391
217
 
392
- From the monorepo root:
393
-
394
- ```bash
395
- yarn workspace @cmflow/atlas build
396
- yarn workspace @cmflow/atlas test
397
- ```
398
218
 
399
219
  ## License
400
220
 
401
- LicenseThe MIT License (MIT)Copyright (c) 2016 - Today ClubMed
221
+ The MIT License (MIT)
222
+
223
+ Copyright (c) 2016 - Today ClubMed
402
224
 
403
225
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.