@trackunit/iris-app 1.12.9 → 1.12.11
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/CHANGELOG.md +19 -0
- package/package.json +2 -2
- package/src/executors/submit/executor.js.map +1 -0
- package/src/executors/unpublish/executor.js.map +1 -0
- package/src/executors/utils/authentication.js.map +1 -0
- package/src/executors/utils/irisAppServerSettings.js.map +1 -0
- package/src/executors/utils/src/index.js.map +1 -0
- package/src/generators/ai-agent-sync/README.md +5 -2
- package/src/generators/ai-agent-sync/generator.d.ts +1 -1
- package/src/generators/ai-agent-sync/generator.js +29 -4
- package/src/generators/ai-agent-sync/generator.js.map +1 -0
- package/src/generators/create/generator.js.map +1 -0
- package/src/generators/extend/dependencies.js.map +1 -0
- package/src/generators/extend/generator.js.map +1 -0
- package/src/generators/preset/files/.agents/skills/browser-testing/SKILL.md +193 -0
- package/src/generators/preset/files/.agents/skills/create-app/SKILL.md +191 -0
- package/src/generators/preset/files/.agents/skills/customfields/SKILL.md +239 -0
- package/src/generators/preset/files/.agents/skills/graphql/SKILL.md +147 -0
- package/src/generators/preset/files/.agents/skills/graphql-timeseries/SKILL.md +193 -0
- package/src/generators/preset/files/.agents/skills/irisx-app-sdk/SKILL.md +116 -0
- package/src/generators/preset/files/.agents/skills/react-core-hooks/SKILL.md +215 -0
- package/src/generators/preset/files/.agents/skills/tables-and-sorting/SKILL.md +122 -0
- package/src/generators/preset/files/.agents/skills/widget-extensions/SKILL.md +245 -0
- package/src/generators/preset/files/.cursor/mcp.json +4 -0
- package/src/generators/preset/generator.js.map +1 -0
- package/src/generators/preset/root-files/AGENTS.md +43 -0
- package/src/generators/preset/root-files/CLAUDE.md +17 -0
- package/src/index.js.map +1 -0
- package/src/utils/ast/astUtils.js.map +1 -0
- package/src/utils/fileUpdater.js.map +1 -0
- package/src/generators/preset/files/.cursor/commands/create-app.md +0 -226
- package/src/generators/preset/files/.cursor/rules/browser-irisx-development.mdc +0 -246
- package/src/generators/preset/files/.cursor/rules/graphql-timeseries.md +0 -260
- package/src/generators/preset/files/.cursor/rules/irisx-app-sdk-customfields.md +0 -305
- package/src/generators/preset/files/.cursor/rules/irisx-app-sdk-graphql.md +0 -30
- package/src/generators/preset/files/.cursor/rules/irisx-app-sdk.mdc +0 -82
- package/src/generators/preset/files/.cursor/rules/react-core-hooks.md +0 -155
- package/src/generators/preset/files/.cursor/rules/rules-index.mdc +0 -10
- package/src/generators/preset/files/.cursor/rules/structured-development.mdc +0 -86
- package/src/generators/preset/files/.cursor/rules/tables-and-sorting.mdc +0 -126
- package/src/generators/preset/files/.cursor/rules/widget-extensions.md +0 -323
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
## 1.12.11 (2026-03-06)
|
|
2
|
+
|
|
3
|
+
### 🧱 Updated Dependencies
|
|
4
|
+
|
|
5
|
+
- Updated iris-app-build-utilities to 1.12.64
|
|
6
|
+
- Updated iris-app-api to 1.14.58
|
|
7
|
+
|
|
8
|
+
## 1.12.10 (2026-03-06)
|
|
9
|
+
|
|
10
|
+
### 🩹 Fixes
|
|
11
|
+
|
|
12
|
+
- address PR review - chrome-devtools MCP, useWidgetConfig consistency ([de581c854a5](https://github.com/Trackunit/manager/commit/de581c854a5))
|
|
13
|
+
- clean up old .cursor/rules and .cursor/commands files during ai-agent-sync ([e7abc4294ab](https://github.com/Trackunit/manager/commit/e7abc4294ab))
|
|
14
|
+
|
|
15
|
+
### ❤️ Thank You
|
|
16
|
+
|
|
17
|
+
- Cursor Agent @cursoragent
|
|
18
|
+
- Kasper Laursen @ghost-of-kla-trackunit
|
|
19
|
+
|
|
1
20
|
## 1.12.9 (2026-03-06)
|
|
2
21
|
|
|
3
22
|
### 🧱 Updated Dependencies
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trackunit/iris-app",
|
|
3
|
-
"version": "1.12.
|
|
3
|
+
"version": "1.12.11",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"generators": "./generators.json",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"@npmcli/arborist": "^9.1.9",
|
|
27
27
|
"win-ca": "^3.5.1",
|
|
28
28
|
"@trackunit/shared-utils": "1.13.55",
|
|
29
|
-
"@trackunit/iris-app-api": "1.14.
|
|
29
|
+
"@trackunit/iris-app-api": "1.14.58",
|
|
30
30
|
"tslib": "^2.6.2",
|
|
31
31
|
"@clack/prompts": "^1.0.0",
|
|
32
32
|
"@npm/types": "^1.0.2"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../libs/iris-app-sdk/iris-app/src/executors/submit/executor.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-console */\nimport { PackageJson } from \"@npm/types\";\nimport { Arborist } from \"@npmcli/arborist\";\nimport { checkPackageVersion } from \"@trackunit/iris-app-build-utilities\";\nimport * as libpub from \"libnpmpublish\";\nimport * as pacote from \"pacote\";\nimport readline from \"readline\";\nimport { inject } from \"win-ca\";\nimport { getAccessToken } from \"../utils/authentication\";\nimport { getSettings, Settings } from \"../utils/irisAppServerSettings\";\nimport { SubmitExecutorSchema } from \"./schema\";\n\n// Inject Windows trusted certificates to support Zscalar and other traffic inspection systems.\ninject(\"+\");\n\ntype SubmitError = Error & { statusCode?: number; code?: string; headers?: { [key: string]: string } };\n\nclass NpmConflictError extends Error {}\nclass NpmGeneralError extends Error {}\nclass ApproveError extends Error {}\n\nfunction sleep(time: number) {\n return new Promise(resolve => setTimeout(resolve, time));\n}\n\n/**\n * Submit the package to the npm registry.\n *\n * @param {SubmitExecutorSchema} options The options provided to the executor.\n * @returns {Promise<{ success: boolean }>} The result of the submit.\n */\nexport default async function runExecutor(options: SubmitExecutorSchema) {\n await checkPackageVersion(true);\n const settings = getSettings();\n const linkToTerms = \"https://trackunit.com/terms-conditions-marketplace/\";\n\n try {\n if (options.devTermsAndConditions?.toLowerCase() !== \"accept\" && !settings.devTermsAccept) {\n // Ask user if they accept dev terms and conditions.\n const userInput = await promptUserForInput(\n `Do you accept the developer terms and conditions? \\n(${linkToTerms}) \\n\\n 📝 Type 'accept' to proceed: `\n );\n if (userInput.toLowerCase() !== \"accept\") {\n throw new Error(`You must accept the developer terms and conditions (${linkToTerms}) to continue.`);\n }\n }\n const tokenData = await getAccessToken(settings.env);\n\n if (\"access_token\" in tokenData) {\n console.log(\"🥳 Successfully authenticated.\");\n\n const manifest = (await pacote.manifest(options.inputPath)) as PackageJson;\n const tarData = await pacote.tarball(options.inputPath, { Arborist });\n\n return await doUploadAppWithRetry(tokenData.access_token, manifest, tarData, settings, 10);\n } else if (\"error\" in tokenData) {\n if (tokenData.error === \"expired_token\") {\n throw new Error(\"⌛️ Authentication attempt expired\");\n } else {\n throw new Error(`Error occurred: ${tokenData.error} ${tokenData.error_description}`);\n }\n } else {\n throw new Error(\"Unknown error occurred\");\n }\n } catch (e) {\n console.error(\"❌ \", e);\n return { success: false };\n }\n}\n\nasync function doUploadAppWithRetry(\n accessToken: string,\n manifest: PackageJson,\n tarData: Buffer & pacote.FetchResult,\n settings: Settings,\n retryCount: number\n): Promise<{ success: boolean }> {\n try {\n return await doUploadApp(accessToken, manifest, tarData, settings);\n } catch (e) {\n if (e instanceof NpmConflictError) {\n console.error(\"❌ Unable to ship app package. Cannot submit over existing version.\");\n return { success: false };\n } else {\n if (retryCount > 1) {\n console.error(\"⚠️ Unable to ship app package. Got error from Iris App SDK repository. Retrying submit...\", e);\n await sleep(30000);\n return await doUploadAppWithRetry(accessToken, manifest, tarData, settings, retryCount - 1);\n } else {\n console.error(\"❌ Unable to ship app package. Got error from Iris App SDK repository.\", e);\n return { success: false };\n }\n }\n }\n}\n\nasync function doUploadApp(\n accessToken: string,\n manifest: PackageJson,\n tarData: Buffer & pacote.FetchResult,\n settings: Settings\n): Promise<{ success: boolean }> {\n const npmFetchOptions: { registry?: string } & Record<string, string | boolean> = {};\n npmFetchOptions.registry = settings.repoUrl.toString();\n const repoHostAndPort = settings.repoUrl.hostname + (settings.repoUrl.port ? \":\" + settings.repoUrl.port : \"\");\n npmFetchOptions[`//${repoHostAndPort}${settings.repoUrl.pathname}:_authToken`] = accessToken;\n npmFetchOptions[`//${repoHostAndPort}${settings.repoUrl.pathname}/repo/:always-auth`] = true;\n\n console.log(\"🚢 Shipping the app package...\");\n const submitResult = await libpub.publish(manifest, tarData, npmFetchOptions).catch((err: SubmitError) => {\n if (err.statusCode === 409 || err.code === \"E409\" || err.code === \"EPUBLISHCONFLICT\") {\n return {\n ok: false,\n publishConflict: true,\n };\n } else {\n return {\n ok: false,\n headers: new Headers(err.headers),\n statusText: `Error`,\n text: () => Promise.resolve(`${err.name} ${err.message}`),\n };\n }\n });\n\n const warningsText = submitResult.headers?.get(\"TU-IRIS-APP-WARNINGS\");\n if (warningsText) {\n console.log(\"⚠️ \" + decodeURI(warningsText));\n }\n\n if (submitResult.ok) {\n console.log(`🚀 Uploaded the app package version ${manifest.version}`);\n\n return await doApproveAppWithRetry(accessToken, manifest, settings, 3);\n } else if (\"publishConflict\" in submitResult) {\n if (process.env.SKIP_EXISTING === \"true\") {\n console.log(`⏩ Skipped submitting ${manifest.version} because the version is already submitted`);\n return await doApproveAppWithRetry(accessToken, manifest, settings, 3);\n } else {\n throw new NpmConflictError();\n }\n } else {\n throw new NpmGeneralError(\n submitResult.statusText +\n \" \" +\n (await submitResult.text()) +\n \". Trace ID: \" +\n submitResult.headers.get(\"trace-id\")\n );\n }\n}\n\nasync function promptUserForInput(query: string): Promise<string> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n return new Promise(resolve => {\n rl.question(query, (input: string) => {\n rl.close();\n resolve(input);\n });\n });\n}\n\nasync function doApproveAppWithRetry(\n token: string,\n manifest: PackageJson,\n settings: Settings,\n retryCount: number\n): Promise<{ success: boolean }> {\n try {\n return await doApproveApp(token, manifest, settings);\n } catch (e) {\n if (e instanceof ApproveError) {\n if (retryCount > 1) {\n console.error(\n \"⚠️ Unable to approve app package. Got approve error from Iris App SDK repository. Retrying approve...\",\n e\n );\n await sleep(30000);\n return await doApproveAppWithRetry(token, manifest, settings, retryCount - 1);\n } else {\n console.error(\"❌ Unable to approve app package. Got approve error from Iris App SDK repository.\", e);\n return { success: false };\n }\n } else {\n console.error(\"❌ Unable to approve app package. Got error from Iris App SDK repository.\", e);\n return { success: false };\n }\n }\n}\n\nasync function doApproveApp(token: string, manifest: PackageJson, settings: Settings) {\n if (process.env.TU_APPROVE === \"true\") {\n console.log(`🖋️ Approving the app...`);\n const approveResult = await fetch(new URL(`${manifest.name}@${manifest.version}`, settings.approvalUrl), {\n method: \"PUT\",\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (approveResult.ok) {\n console.log(`✅ Approved version ${manifest.version} of ${manifest.name}.`);\n return { success: true };\n } else {\n throw new ApproveError(\n `${approveResult.statusText}, ${await approveResult.text()}, Trace ID: ${approveResult.headers.get(\"trace-id\")}`\n );\n }\n } else {\n return { success: true };\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../libs/iris-app-sdk/iris-app/src/executors/unpublish/executor.ts"],"names":[],"mappings":";;AAcA,8BAkDC;;AA9DD,uDAAiC;AACjC,kBAAgB;AAChB,4DAAyD;AACzD,0EAA6D;AAG7D;;;;;GAKG;AACY,KAAK,UAAU,WAAW,CAAC,OAAgC;IACxE,MAAM,QAAQ,GAAG,IAAA,mCAAW,GAAE,CAAC;IAE/B,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,MAAM,IAAA,+BAAc,EAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAErD,IAAI,cAAc,IAAI,SAAS,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;YAE9C,MAAM,QAAQ,GAAG,CAAC,MAAM,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAgB,CAAC;YAC3E,MAAM,eAAe,GAAG,MAAM,KAAK,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE;gBAC5E,MAAM,EAAE,QAAQ;gBAChB,OAAO,EAAE;oBACP,aAAa,EAAE,UAAU,SAAS,CAAC,YAAY,EAAE;iBAClD;aACF,CAAC,CAAC;YACH,IAAI,eAAe,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBACnC,QAAQ,eAAe,CAAC,MAAM,EAAE,CAAC;oBAC/B,KAAK,GAAG;wBACN,MAAM,IAAI,KAAK,CACb,6DAA6D,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CACvG,CAAC;oBACJ,KAAK,GAAG;wBACN,MAAM,IAAI,KAAK,CACb,wDAAwD,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAClG,CAAC;oBACJ,KAAK,GAAG;wBACN,MAAM,IAAI,KAAK,CACb,iEAAiE,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAC3G,CAAC;oBACJ;wBACE,MAAM,IAAI,KAAK,CAAC,GAAG,eAAe,CAAC,UAAU,eAAe,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;gBAC3G,CAAC;YACH,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;YAChD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;aAAM,IAAI,OAAO,IAAI,SAAS,EAAE,CAAC;YAChC,IAAI,SAAS,CAAC,KAAK,KAAK,eAAe,EAAE,CAAC;gBACxC,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;YACvD,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,KAAK,CAAC,mBAAmB,SAAS,CAAC,KAAK,IAAI,SAAS,CAAC,iBAAiB,EAAE,CAAC,CAAC;YACvF,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACvB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC5B,CAAC;AACH,CAAC","sourcesContent":["/* eslint-disable no-console */\nimport { PackageJson } from \"nx/src/utils/package-json\";\nimport * as pacote from \"pacote\";\nimport \"win-ca\";\nimport { getAccessToken } from \"../utils/authentication\";\nimport { getSettings } from \"../utils/irisAppServerSettings\";\nimport { UnpublishExecutorSchema } from \"./schema\";\n\n/**\n * Unpublish an app from the Trackunit Marketplace.\n *\n * @param {UnpublishExecutorSchema} options options provided to the executor.\n * @returns {Promise<{ success: boolean }>} The result of the unpublish.\n */\nexport default async function runExecutor(options: UnpublishExecutorSchema) {\n const settings = getSettings();\n\n try {\n const tokenData = await getAccessToken(settings.env);\n\n if (\"access_token\" in tokenData) {\n console.log(\"🥳 Successfully authenticated.\");\n\n const manifest = (await pacote.manifest(options.inputPath)) as PackageJson;\n const unpublishResult = await fetch(new URL(manifest.name, settings.repoUrl), {\n method: \"DELETE\",\n headers: {\n Authorization: `Bearer ${tokenData.access_token}`,\n },\n });\n if (unpublishResult.status !== 200) {\n switch (unpublishResult.status) {\n case 401:\n throw new Error(\n `Unpublishing failed due to invalid credentials, Trace ID: ${unpublishResult.headers.get(\"trace-id\")}`\n );\n case 403:\n throw new Error(\n `You are not allowed to unpublish this app, Trace ID: ${unpublishResult.headers.get(\"trace-id\")}`\n );\n case 404:\n throw new Error(\n `The app you are trying to unpublish does not exist, Trace ID: ${unpublishResult.headers.get(\"trace-id\")}`\n );\n default:\n throw new Error(`${unpublishResult.statusText}, Trace ID: ${unpublishResult.headers.get(\"trace-id\")}`);\n }\n }\n\n console.log(\"🥳 Successfully unpublished app.\");\n return { success: true };\n } else if (\"error\" in tokenData) {\n if (tokenData.error === \"expired_token\") {\n throw new Error(\"⌛️ Authentication attempt expired\");\n } else {\n throw new Error(`Error occurred: ${tokenData.error} ${tokenData.error_description}`);\n }\n } else {\n throw new Error(\"Unknown error occurred\");\n }\n } catch (e) {\n console.error(\"❌ \", e);\n return { success: false };\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authentication.js","sourceRoot":"","sources":["../../../../../../../libs/iris-app-sdk/iris-app/src/executors/utils/authentication.ts"],"names":[],"mappings":";;AA0CA,wCAqFC;;AA/HD,+BAA+B;AAC/B,wDAA+B;AAmC/B;;;;;GAKG;AACI,KAAK,UAAU,cAAc,CAAC,GAAW;IAC9C,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IACtC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC;IAC7D,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC;IACrE,0DAA0D;IAC1D,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QACzB,OAAO;YACL,UAAU,EAAE,QAAQ;YACpB,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ;YAC9B,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ;YAClC,UAAU,EAAE,CAAC;YACb,KAAK,EAAE,SAAS;SACjB,CAAC;QACF,uFAAuF;QACvF,mCAAmC;IACrC,CAAC;SAAM,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAClC,IAAI,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,2CAA2C,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC;QAC7E,CAAC;QACD,IAAI,YAAY,KAAK,SAAS,IAAI,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC7D,MAAM,IAAI,KAAK,CAAC,+CAA+C,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC;QACjF,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,eAAe,EAAE,CAAC;QAC1C,WAAW,CAAC,MAAM,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;QAC1C,WAAW,CAAC,MAAM,CAAC,eAAe,EAAE,YAAY,CAAC,CAAC;QAClD,WAAW,CAAC,MAAM,CAAC,YAAY,EAAE,oBAAoB,CAAC,CAAC;QACvD,WAAW,CAAC,MAAM,CAAC,OAAO,EAAE,wCAAwC,CAAC,CAAC;QACtE,MAAM,aAAa,GAAG,MAAM,KAAK,CAAC,GAAG,QAAQ,CAAC,kCAAkC,WAAW,EAAE;YAC3F,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,WAAW;SAClB,CAAC,CAAC;QACH,OAAO,CAAC,MAAM,aAAa,CAAC,IAAI,EAAE,CAAc,CAAC;QACjD,gDAAgD;QAChD,+CAA+C;IACjD,CAAC;SAAM,CAAC;QACN,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;QAC9C,eAAe,CAAC,MAAM,CAAC,WAAW,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACvD,eAAe,CAAC,MAAM,CAAC,OAAO,EAAE,2BAA2B,CAAC,CAAC;QAC7D,MAAM,iBAAiB,GAAG,MAAM,KAAK,CAAC,GAAG,QAAQ,CAAC,gCAAgC,sBAAsB,EAAE;YACxG,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,eAAe;SACtB,CAAC,CAAC;QACH,MAAM,aAAa,GAAG,CAAC,MAAM,iBAAiB,CAAC,IAAI,EAAE,CAAkB,CAAC;QAExE,IAAI,OAAO,IAAI,aAAa,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,mBAAmB,aAAa,CAAC,KAAK,IAAI,aAAa,CAAC,iBAAiB,EAAE,CAAC,CAAC;QAC/F,CAAC;aAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,EAAE,CAAC;YACpD,MAAM,IAAI,KAAK,CAAC,6BAA6B,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;QAChF,CAAC;QAED,OAAO,CAAC,GAAG,CACT,qOAAqO,aAAa,CAAC,yBAAyB,EAAE,CAC/Q,CAAC;QACF,IAAI,CAAC;YACH,8DAA8D;YAC9D,MAAM,CAAE,cAAmB,CAAC,OAAO,CAAC,CAAC,CAAE,cAAmB,CAAC,OAAO,CAAC,CAAC,CAAC,cAAW,CAAC,CAC/E,aAAa,CAAC,yBAAyB,CACxC,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,wEAAwE;QAC1E,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;QAChE,IAAI,SAAS,GAAqB,IAAI,CAAC;QACvC,GAAG,CAAC;YACF,MAAM,KAAK,CAAC,aAAa,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;YAC3C,IAAI,SAAS,IAAI,OAAO,IAAI,SAAS,IAAI,SAAS,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;gBACzE,MAAM,KAAK,CAAC,KAAK,CAAC,CAAC;YACrB,CAAC;YACD,MAAM,WAAW,GAAG,IAAI,eAAe,EAAE,CAAC;YAC1C,WAAW,CAAC,MAAM,CAAC,WAAW,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACnD,WAAW,CAAC,MAAM,CAAC,YAAY,EAAE,8CAA8C,CAAC,CAAC;YACjF,WAAW,CAAC,MAAM,CAAC,aAAa,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;YAC7D,MAAM,aAAa,GAAG,MAAM,KAAK,CAAC,GAAG,QAAQ,CAAC,gCAAgC,WAAW,EAAE;gBACzF,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,WAAW;aAClB,CAAC,CAAC;YACH,SAAS,GAAG,CAAC,MAAM,aAAa,CAAC,IAAI,EAAE,CAAc,CAAC;QACxD,CAAC,QACC,CAAC,CAAC,UAAU,IAAI,SAAS,CAAC;YAC1B,CAAC,CAAC,OAAO,IAAI,SAAS,IAAI,SAAS,CAAC,KAAK,KAAK,uBAAuB,IAAI,SAAS,CAAC,KAAK,KAAK,WAAW,CAAC,EACzG;QACF,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,GAAW;IAClC,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,MAAM;YACT,OAAO;gBACL,QAAQ,EAAE,sBAAsB;gBAChC,gCAAgC,EAAE,iEAAiE;gBACnG,kCAAkC,EAAE,iEAAiE;gBACrG,GAAG;aACJ,CAAC;QACJ,KAAK,OAAO;YACV,OAAO;gBACL,QAAQ,EAAE,sBAAsB;gBAChC,gCAAgC,EAAE,uEAAuE;gBACzG,kCAAkC,EAAE,uEAAuE;gBAC3G,GAAG;aACJ,CAAC;QACJ,KAAK,KAAK;YACR,OAAO;gBACL,QAAQ,EAAE,sBAAsB;gBAChC,gCAAgC,EAAE,qEAAqE;gBACvG,kCAAkC,EAAE,qEAAqE;gBACzG,GAAG;aACJ,CAAC;QACJ;YACE,MAAM,IAAI,KAAK,CAAC,wBAAwB,GAAG,EAAE,CAAC,CAAC;IACnD,CAAC;AACH,CAAC;AAED,SAAS,KAAK,CAAC,IAAY;IACzB,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;AAC3D,CAAC","sourcesContent":["/* eslint-disable no-console */\nimport openBrowser from \"open\";\n\nexport interface AuthSettings {\n env: string;\n publicAuthorizationServerBaseUrl: string;\n internalAuthorizationServerBaseUrl: string;\n clientId: string;\n}\n\ninterface OktaError {\n error: string;\n error_description: string;\n}\n\ninterface AuthorizeDataSuccess {\n device_code: string;\n user_code: string;\n verification_uri: string;\n verification_uri_complete: string;\n expires_in: number;\n interval: number;\n}\n\ntype AuthorizeData = AuthorizeDataSuccess | OktaError;\n\nexport interface TokenDataSuccess {\n token_type: string;\n expires_in: number;\n access_token: string;\n scope: string;\n id_token: string;\n}\n\ntype TokenData = OktaError | TokenDataSuccess;\n\n/**\n * Authenticate and get access token\n *\n * @param {AuthSettings} env Settings used for authentication\n * @returns {*} {Promise<TokenData>}\n */\nexport async function getAccessToken(env: string): Promise<TokenData> {\n const settings = getAuthSettings(env);\n const clientId = process.env[`TU_CLIENT_ID_${settings.env}`];\n const clientSecret = process.env[`TU_CLIENT_SECRET_${settings.env}`];\n // use token provided as environment variable if available\n if (process.env.TU_TOKEN) {\n return {\n token_type: \"Bearer\",\n id_token: process.env.TU_TOKEN,\n access_token: process.env.TU_TOKEN,\n expires_in: 0,\n scope: \"unknown\",\n };\n // use client id and secret provided as environment variables to fetch a token directly\n // This is used for CI/CD pipelines\n } else if (clientId !== undefined) {\n if (clientId.trim() === \"\") {\n throw new Error(`Missing environment value: TU_CLIENT_ID_${settings.env}`);\n }\n if (clientSecret === undefined || clientSecret.trim() === \"\") {\n throw new Error(`Missing environment value: TU_CLIENT_SECRET_${settings.env}`);\n }\n\n const tokenParams = new URLSearchParams();\n tokenParams.append(\"client_id\", clientId);\n tokenParams.append(\"client_secret\", clientSecret);\n tokenParams.append(\"grant_type\", \"client_credentials\");\n tokenParams.append(\"scope\", \"core.iris.app.publish_for_all_accounts\");\n const tokenResponse = await fetch(`${settings.internalAuthorizationServerBaseUrl}/v1/token`, {\n method: \"POST\",\n body: tokenParams,\n });\n return (await tokenResponse.json()) as TokenData;\n // ask the user to authenticated using a browser\n // and fetch a token using the device code flow\n } else {\n const authorizeParams = new URLSearchParams();\n authorizeParams.append(\"client_id\", settings.clientId);\n authorizeParams.append(\"scope\", \"openid profile fms assume\");\n const authorizeResponse = await fetch(`${settings.publicAuthorizationServerBaseUrl}/v1/device/authorize`, {\n method: \"POST\",\n body: authorizeParams,\n });\n const authorizeData = (await authorizeResponse.json()) as AuthorizeData;\n\n if (\"error\" in authorizeData) {\n throw new Error(`Error occurred: ${authorizeData.error} ${authorizeData.error_description}`);\n } else if (!authorizeData.verification_uri_complete) {\n throw new Error(`Missing verification URI: ${JSON.stringify(authorizeData)}`);\n }\n\n console.log(\n `🔐 Attempting to automatically open the Trackunit authentication page in your default browser...\\n If the browser does not open or you wish to use a different device to authorize this request, open the following URL:\\n\\n ${authorizeData.verification_uri_complete}`\n );\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n await ((openBrowser as any).default ? (openBrowser as any).default : openBrowser)(\n authorizeData.verification_uri_complete\n );\n } catch (error) {\n // safe to ignore, since we ask the user to open the URL manually above.\n }\n\n console.log(\"\\n⏳ Waiting for authentication in the browser...\");\n let tokenData: TokenData | null = null;\n do {\n await sleep(authorizeData.interval * 1000);\n if (tokenData && \"error\" in tokenData && tokenData.error === \"slow_down\") {\n await sleep(10000);\n }\n const tokenParams = new URLSearchParams();\n tokenParams.append(\"client_id\", settings.clientId);\n tokenParams.append(\"grant_type\", \"urn:ietf:params:oauth:grant-type:device_code\");\n tokenParams.append(\"device_code\", authorizeData.device_code);\n const tokenResponse = await fetch(`${settings.publicAuthorizationServerBaseUrl}/v1/token`, {\n method: \"POST\",\n body: tokenParams,\n });\n tokenData = (await tokenResponse.json()) as TokenData;\n } while (\n !(\"id_token\" in tokenData) &&\n !(\"error\" in tokenData && tokenData.error !== \"authorization_pending\" && tokenData.error !== \"slow_down\")\n );\n return tokenData;\n }\n}\n\n/**\n *\n */\nfunction getAuthSettings(env: string): AuthSettings {\n switch (env) {\n case \"PROD\":\n return {\n clientId: \"0oamfeklvodROR2ul357\",\n publicAuthorizationServerBaseUrl: \"https://identity.iris.trackunit.com/oauth2/aus2u3jix1dWU7fwt356\",\n internalAuthorizationServerBaseUrl: \"https://identity.iris.trackunit.com/oauth2/aushbxvmpdlWrMnO6357\",\n env,\n };\n case \"STAGE\":\n return {\n clientId: \"0oa1q2vmx21NcFLOs0h8\",\n publicAuthorizationServerBaseUrl: \"https://identity.stage.iris.trackunit.com/oauth2/aus1owd7wny5YVsU00h8\",\n internalAuthorizationServerBaseUrl: \"https://identity.stage.iris.trackunit.com/oauth2/aus1o484n9xEHT7G50h8\",\n env,\n };\n case \"DEV\":\n return {\n clientId: \"0oamebigau4RkaqZ6357\",\n publicAuthorizationServerBaseUrl: \"https://identity.dev.iris.trackunit.com/oauth2/ausj7eh9zeiFhLk4m357\",\n internalAuthorizationServerBaseUrl: \"https://identity.dev.iris.trackunit.com/oauth2/aush09l7x4mDGKxLu357\",\n env,\n };\n default:\n throw new Error(`Unknown environment: ${env}`);\n }\n}\n\nfunction sleep(time: number) {\n return new Promise(resolve => setTimeout(resolve, time));\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"irisAppServerSettings.js","sourceRoot":"","sources":["../../../../../../../libs/iris-app-sdk/iris-app/src/executors/utils/irisAppServerSettings.ts"],"names":[],"mappings":";;AAUA,kCAWC;AAdD;;GAEG;AACH,SAAgB,WAAW;IACzB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,MAAM,CAAC;IACxD,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;IAChC,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,2BAA2B,EAAE,WAAW,EAAE,KAAK,QAAQ,CAAC;IAE3F,OAAO;QACL,WAAW,EAAE,IAAI,GAAG,CAAC,UAAU,EAAE,OAAO,CAAC;QACzC,OAAO,EAAE,IAAI,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC;QAClC,GAAG;QACH,cAAc;KACf,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,GAAG,CAAC,GAAW,EAAE,EAAE;IACjC,QAAQ,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC;QAC1B,KAAK,MAAM;YACT,OAAO,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,6BAA6B,CAAC,CAAC;QACxE,KAAK,OAAO;YACV,OAAO,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,mCAAmC,CAAC,CAAC;QAC9E,KAAK,KAAK;YACR,OAAO,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,iCAAiC,CAAC,CAAC;QAC5E;YACE,MAAM,IAAI,KAAK,CAAC,wBAAwB,GAAG,EAAE,CAAC,CAAC;IACnD,CAAC;AACH,CAAC,CAAA","sourcesContent":["export type Settings = {\n approvalUrl: URL;\n repoUrl: URL;\n env: string;\n devTermsAccept: boolean;\n};\n\n/**\n * Provides the settings for the Iris App server based on the environment.\n */\nexport function getSettings(): Settings {\n const env = process.env.TU_ENV?.toUpperCase() ?? \"PROD\";\n const baseUrl = getBaseUrl(env);\n const devTermsAccept = process.env.TU_DEV_TERMS_AND_CONDITIONS?.toLowerCase() === \"accept\";\n\n return {\n approvalUrl: new URL(\"approve/\", baseUrl),\n repoUrl: new URL(\"repo/\", baseUrl),\n env,\n devTermsAccept,\n };\n}\n\n/**\n * Provides the base URL for the Iris App server based on the environment.\n *\n * @param {string} env The environment to get the base URL for.\n * @returns {URL} The base URL for the Iris App server.\n */\nconst getBaseUrl = (env: string) => {\n switch (env.toUpperCase()) {\n case \"PROD\":\n return new URL(process.env.BASE_URL ?? \"https://iris.trackunit.app/\");\n case \"STAGE\":\n return new URL(process.env.BASE_URL ?? \"https://stage.iris.trackunit.app/\");\n case \"DEV\":\n return new URL(process.env.BASE_URL ?? \"https://dev.iris.trackunit.app/\");\n default:\n throw new Error(`Unknown environment: ${env}`);\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../../libs/iris-app-sdk/iris-app/src/executors/utils/src/index.js"],"names":[],"mappings":";AAAA,wFAAwF","sourcesContent":["// Empty ts file for webpack to be happy - we generate module federated js files instead\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# AI Agent Sync Generator
|
|
2
2
|
|
|
3
|
-
Syncs
|
|
3
|
+
Syncs agent skills, AGENTS.md, CLAUDE.md, and AI agent configuration files to the latest version. Ensures the SDK is at the latest version before applying updates.
|
|
4
4
|
|
|
5
5
|
## Usage
|
|
6
6
|
|
|
@@ -10,7 +10,10 @@ nx g @trackunit/iris-app:ai-agent-sync
|
|
|
10
10
|
|
|
11
11
|
## What it syncs
|
|
12
12
|
|
|
13
|
-
- `.
|
|
13
|
+
- `.agents/skills/` - AI agent skills for the IrisX App SDK (editor-agnostic)
|
|
14
|
+
- `.cursor/mcp.json` - Cursor-specific MCP configuration
|
|
15
|
+
- `AGENTS.md` - Workspace-level agent instructions (always applied)
|
|
16
|
+
- `CLAUDE.md` - Claude-specific configuration (references AGENTS.md)
|
|
14
17
|
|
|
15
18
|
## Flow
|
|
16
19
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Tree } from "@nx/devkit";
|
|
2
2
|
import { AiAgentSyncGeneratorSchema } from "./schema";
|
|
3
3
|
/**
|
|
4
|
-
* Syncs Cursor
|
|
4
|
+
* Syncs Cursor skills, AGENTS.md, CLAUDE.md, and AI agent configuration files.
|
|
5
5
|
* Requires the SDK to be at the latest version before running.
|
|
6
6
|
*/
|
|
7
7
|
export declare function aiAgentSyncGenerator(tree: Tree, options: AiAgentSyncGeneratorSchema): Promise<void>;
|
|
@@ -50,7 +50,7 @@ function ensureUpdateScript(tree) {
|
|
|
50
50
|
});
|
|
51
51
|
}
|
|
52
52
|
/**
|
|
53
|
-
* Syncs Cursor
|
|
53
|
+
* Syncs Cursor skills, AGENTS.md, CLAUDE.md, and AI agent configuration files.
|
|
54
54
|
* Requires the SDK to be at the latest version before running.
|
|
55
55
|
*/
|
|
56
56
|
async function aiAgentSyncGenerator(tree, options) {
|
|
@@ -74,9 +74,34 @@ async function aiAgentSyncGenerator(tree, options) {
|
|
|
74
74
|
`Then run this generator again.`);
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
|
-
//
|
|
78
|
-
const
|
|
79
|
-
|
|
77
|
+
// Clean up old .cursor/rules and .cursor/commands files that were managed by previous versions
|
|
78
|
+
const oldManagedFiles = [
|
|
79
|
+
".cursor/rules/irisx-app-sdk.mdc",
|
|
80
|
+
".cursor/rules/rules-index.mdc",
|
|
81
|
+
".cursor/rules/structured-development.mdc",
|
|
82
|
+
".cursor/rules/browser-irisx-development.mdc",
|
|
83
|
+
".cursor/rules/graphql-timeseries.md",
|
|
84
|
+
".cursor/rules/irisx-app-sdk-customfields.md",
|
|
85
|
+
".cursor/rules/irisx-app-sdk-graphql.md",
|
|
86
|
+
".cursor/rules/react-core-hooks.md",
|
|
87
|
+
".cursor/rules/tables-and-sorting.mdc",
|
|
88
|
+
".cursor/rules/widget-extensions.md",
|
|
89
|
+
".cursor/commands/create-app.md",
|
|
90
|
+
];
|
|
91
|
+
for (const file of oldManagedFiles) {
|
|
92
|
+
if (tree.exists(file)) {
|
|
93
|
+
tree.delete(file);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Copy Cursor-specific configuration (mcp.json)
|
|
97
|
+
const cursorTemplatePath = path.join(__dirname, "../preset/files/.cursor");
|
|
98
|
+
(0, devkit_1.generateFiles)(tree, cursorTemplatePath, ".cursor", {});
|
|
99
|
+
// Copy agent skills (editor-agnostic)
|
|
100
|
+
const agentsTemplatePath = path.join(__dirname, "../preset/files/.agents");
|
|
101
|
+
(0, devkit_1.generateFiles)(tree, agentsTemplatePath, ".agents", {});
|
|
102
|
+
// Copy AGENTS.md and CLAUDE.md to workspace root
|
|
103
|
+
const rootTemplatePath = path.join(__dirname, "../preset/root-files");
|
|
104
|
+
(0, devkit_1.generateFiles)(tree, rootTemplatePath, ".", {});
|
|
80
105
|
await (0, devkit_1.formatFiles)(tree);
|
|
81
106
|
}
|
|
82
107
|
exports.default = aiAgentSyncGenerator;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../../libs/iris-app-sdk/iris-app/src/generators/ai-agent-sync/generator.ts"],"names":[],"mappings":"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","sourcesContent":["import { Tree, formatFiles, generateFiles, updateJson } from \"@nx/devkit\";\nimport { detectPackageManager, getPackageManagerCommand } from \"nx/src/devkit-exports\";\nimport * as pacote from \"pacote\";\nimport * as path from \"path\";\nimport * as semver from \"semver\";\nimport { AiAgentSyncGeneratorSchema } from \"./schema\";\n\nconst IRIS_APP_PACKAGE = \"@trackunit/iris-app\";\nconst UPDATE_SCRIPT_NAME = \"update:trackunit\";\nconst UPDATE_SCRIPT_CMD = 'npx npm-check-updates \"/@trackunit/\" -u';\n\ntype PackageJson = {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n scripts?: Record<string, string>;\n};\n\nfunction getStringValue(obj: unknown, key: string): string | undefined {\n if (typeof obj === \"object\" && obj !== null && key in obj) {\n const value = (obj as Record<string, unknown>)[key];\n return typeof value === \"string\" ? value : undefined;\n }\n return undefined;\n}\n\n/**\n * Gets the installed version of @trackunit/iris-app from workspace package.json\n */\nfunction getInstalledSdkVersion(tree: Tree): string | undefined {\n const pkgJson: unknown = JSON.parse(tree.read(\"package.json\", \"utf-8\") ?? \"{}\");\n if (typeof pkgJson !== \"object\" || pkgJson === null) {\n return undefined;\n }\n const pkg = pkgJson as Record<string, unknown>;\n return getStringValue(pkg.dependencies, IRIS_APP_PACKAGE) ?? getStringValue(pkg.devDependencies, IRIS_APP_PACKAGE);\n}\n\n/**\n * Fetches the latest version of @trackunit/iris-app from npm\n */\nasync function getLatestSdkVersion(): Promise<string> {\n const manifest = await pacote.manifest(IRIS_APP_PACKAGE);\n return manifest.version;\n}\n\n/**\n * Ensures the update:trackunit script exists in package.json\n */\nfunction ensureUpdateScript(tree: Tree): void {\n updateJson<PackageJson, PackageJson>(tree, \"package.json\", pkgJson => {\n if (!pkgJson.scripts) {\n pkgJson.scripts = {};\n }\n if (!pkgJson.scripts[UPDATE_SCRIPT_NAME]) {\n pkgJson.scripts[UPDATE_SCRIPT_NAME] = UPDATE_SCRIPT_CMD;\n }\n return pkgJson;\n });\n}\n\n/**\n * Syncs Cursor skills, AGENTS.md, CLAUDE.md, and AI agent configuration files.\n * Requires the SDK to be at the latest version before running.\n */\nexport async function aiAgentSyncGenerator(tree: Tree, options: AiAgentSyncGeneratorSchema): Promise<void> {\n // Always ensure the update script exists\n ensureUpdateScript(tree);\n\n // Check SDK version unless skipped\n if (!options.skipVersionCheck) {\n const installedVersion = getInstalledSdkVersion(tree);\n const latestVersion = await getLatestSdkVersion();\n\n if (!installedVersion) {\n throw new Error(`${IRIS_APP_PACKAGE} not found in package.json. Is this an Iris App SDK workspace?`);\n }\n\n const installed = semver.minVersion(installedVersion);\n if (!installed || semver.lt(installed, latestVersion)) {\n const pm = detectPackageManager();\n const pmCmd = getPackageManagerCommand(pm);\n\n throw new Error(\n `${IRIS_APP_PACKAGE} is outdated (installed: ${installedVersion}, latest: ${latestVersion}).\\n\\n` +\n `Run the following commands first:\\n` +\n ` ${pmCmd.run(UPDATE_SCRIPT_NAME)}\\n` +\n ` ${pmCmd.install}\\n\\n` +\n `Then run this generator again.`\n );\n }\n }\n\n // Clean up old .cursor/rules and .cursor/commands files that were managed by previous versions\n const oldManagedFiles = [\n \".cursor/rules/irisx-app-sdk.mdc\",\n \".cursor/rules/rules-index.mdc\",\n \".cursor/rules/structured-development.mdc\",\n \".cursor/rules/browser-irisx-development.mdc\",\n \".cursor/rules/graphql-timeseries.md\",\n \".cursor/rules/irisx-app-sdk-customfields.md\",\n \".cursor/rules/irisx-app-sdk-graphql.md\",\n \".cursor/rules/react-core-hooks.md\",\n \".cursor/rules/tables-and-sorting.mdc\",\n \".cursor/rules/widget-extensions.md\",\n \".cursor/commands/create-app.md\",\n ];\n for (const file of oldManagedFiles) {\n if (tree.exists(file)) {\n tree.delete(file);\n }\n }\n\n // Copy Cursor-specific configuration (mcp.json)\n const cursorTemplatePath = path.join(__dirname, \"../preset/files/.cursor\");\n generateFiles(tree, cursorTemplatePath, \".cursor\", {});\n\n // Copy agent skills (editor-agnostic)\n const agentsTemplatePath = path.join(__dirname, \"../preset/files/.agents\");\n generateFiles(tree, agentsTemplatePath, \".agents\", {});\n\n // Copy AGENTS.md and CLAUDE.md to workspace root\n const rootTemplatePath = path.join(__dirname, \"../preset/root-files\");\n generateFiles(tree, rootTemplatePath, \".\", {});\n\n await formatFiles(tree);\n}\n\nexport default aiAgentSyncGenerator;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../../libs/iris-app-sdk/iris-app/src/generators/create/generator.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n addDependenciesToPackageJson,\n addProjectConfiguration,\n formatFiles,\n generateFiles,\n getWorkspaceLayout,\n installPackagesTask,\n names,\n offsetFromRoot,\n readJsonFile,\n Tree,\n updateJson,\n} from \"@nx/devkit\";\nimport { getNpmScope } from \"@nx/js/src/utils/package-json/get-npm-scope\";\nimport { PackageJson as PackageJsonBase } from \"nx/src/utils/package-json\";\nimport * as pacote from \"pacote\";\nimport * as path from \"path\";\nimport { IrisAppGeneratorSchema } from \"./schema\";\n\ntype PackageJson = PackageJsonBase & {\n engines?: Record<string, string>;\n};\n\ninterface NormalizedSchema extends IrisAppGeneratorSchema {\n projectName: string;\n projectRoot: string;\n projectDirectory: string;\n toNxRoot: string;\n npmScope: string;\n}\n\nfunction normalizeOptions(tree: Tree, options: IrisAppGeneratorSchema): NormalizedSchema {\n const name = names(options.name).fileName;\n const projectDirectory = options.directory ? path.join(options.directory, name) : name;\n const toNxRoot = `../../${projectDirectory.indexOf(\"/\") !== -1 ? \"../\" : \"\"}`;\n const projectName = name.replace(new RegExp(\"/\", \"g\"), \"_\");\n const npmScope = getNpmScope(tree);\n if (!npmScope) {\n throw new Error(\"Could not find npm scope in package.json\");\n }\n const projectRoot = `${getWorkspaceLayout(tree).appsDir}/${projectDirectory}`;\n return {\n ...options,\n projectName,\n projectRoot,\n projectDirectory,\n toNxRoot,\n npmScope,\n };\n}\n\nfunction addFiles(tree: Tree, options: NormalizedSchema, packageJson: PackageJson | null) {\n const nodeVersion = packageJson?.engines?.node ?? \">=20.x\";\n const templateOptions = {\n ...options,\n ...names(options.name),\n offsetFromRoot: offsetFromRoot(options.projectRoot),\n template: \"\",\n nodeVersion,\n };\n generateFiles(tree, path.join(__dirname, \"files\"), options.projectRoot, templateOptions);\n}\n\nconst getManifest = (packageName: string) => {\n return pacote.manifest(\n packageName,\n process.env.TU_NPM_REGISTRY ? { registry: process.env.TU_NPM_REGISTRY } : undefined\n );\n};\n\n/**\n * Iris App Generator.\n * This generator will create a new iris app, you can call this from your own generator.\n *\n * @param tree the nx tree\n * @param options the generator options\n * @returns { Promise<void> } void\n */\nexport const IrisAppGenerator = async function (tree: Tree, options: IrisAppGeneratorSchema) {\n const normalizedOptions = normalizeOptions(tree, options);\n const packageJsonFromNpm = await getManifest(\"@trackunit/iris-app\");\n\n const packageJsonLocally: PackageJson = readJsonFile(path.join(__dirname, \"..\", \"..\", \"..\", \"package.json\"));\n\n if (options.updatePackageJson) {\n if (packageJsonFromNpm.version !== packageJsonLocally.version) {\n // eslint-disable-next-line no-console\n console.warn(\n `⚠️ This version of the iris-app package does not match the version of the iris-app package from NPM JS. Please update using: npm i @trackunit/iris-app@${packageJsonFromNpm.version}`\n );\n }\n\n const reactComponentsPackageJsonFromNpm = getManifest(\"@trackunit/react-components\");\n const reactCoreContextsPackageJsonFromNpm = getManifest(\"@trackunit/react-core-contexts\");\n const cssCorePackageJsonFromNpm = getManifest(\"@trackunit/css-core\");\n\n const tuDependencies = {\n \"@trackunit/react-components\": (await reactComponentsPackageJsonFromNpm).version,\n \"@trackunit/react-core-contexts\": (await reactCoreContextsPackageJsonFromNpm).version,\n \"@trackunit/css-core\": (await cssCorePackageJsonFromNpm).version,\n };\n\n const irisAppSdkVitePackageJsonFromNpm = getManifest(\"@trackunit/iris-app-sdk-vite\");\n const reactCoreContextsTestPackageJsonFromNpm = getManifest(\"@trackunit/react-core-contexts-test\");\n const reactTestSetupPackageJsonFromNpm = getManifest(\"@trackunit/react-test-setup\");\n\n const tuDevDependencies = {\n \"@trackunit/iris-app-sdk-vite\": (await irisAppSdkVitePackageJsonFromNpm).version,\n \"@trackunit/react-core-contexts-test\": (await reactCoreContextsTestPackageJsonFromNpm).version,\n \"@trackunit/react-test-setup\": (await reactTestSetupPackageJsonFromNpm).version,\n };\n\n addDependenciesToPackageJson(\n tree,\n {\n ...tuDependencies,\n tslib: \"2.4.0\",\n react: \"19.0.0\",\n \"react-dom\": \"19.0.0\",\n \"single-spa-react\": \"5.1.4\",\n },\n {\n ...tuDevDependencies,\n nx: \"22.4.4\",\n \"@nx/react\": \"22.4.4\",\n \"@nx/workspace\": \"22.4.4\",\n \"@nx/devkit\": \"22.4.4\",\n \"@nx/eslint-plugin\": \"22.4.4\",\n \"@types/react\": \"19.0.8\",\n eslint: \"9.33.0\",\n \"eslint-plugin-react-hooks\": \"7.0.1\",\n \"eslint-plugin-react\": \"7.37.5\",\n \"eslint-plugin-import\": \"2.32.0\",\n \"eslint-plugin-jsx-a11y\": \"6.10.2\",\n \"typescript-eslint\": \"8.54.0\",\n typescript: \"5.9.3\",\n }\n );\n\n updateJson(tree, \"package.json\", packageJson => {\n packageJson.overrides = {\n react: \"19.0.0\", // to avoid resolution warnings when running npm install\n \"react-dom\": \"19.0.0\", // fix resolution warnings and test\n \"zod-validation-error\": \"4.0.2\",\n };\n return packageJson;\n });\n }\n addProjectConfiguration(tree, normalizedOptions.projectName, {\n root: normalizedOptions.projectRoot,\n projectType: \"application\",\n sourceRoot: `${normalizedOptions.projectRoot}/src`,\n targets: {\n build: {\n executor: \"@trackunit/iris-app-sdk-vite:build\",\n options: {\n viteConfig: `${normalizedOptions.projectRoot}/vite.config.ts`,\n outputPath: `dist/${normalizedOptions.projectRoot}`,\n },\n outputs: [\"{options.outputPath}\"],\n },\n serve: {\n executor: \"@trackunit/iris-app-sdk-vite:serve\",\n options: {\n viteConfig: `${normalizedOptions.projectRoot}/vite.config.ts`,\n },\n outputs: [\"{options.outputPath}\"],\n },\n submitApp: {\n executor: \"@trackunit/iris-app:submit\",\n dependsOn: [\"build\"],\n options: {\n inputPath: `dist/${normalizedOptions.projectRoot}`,\n },\n outputs: [\"{workspaceRoot}/dist/\" + normalizedOptions.projectRoot],\n },\n unpublishApp: {\n executor: \"@trackunit/iris-app:unpublish\",\n options: {\n inputPath: `dist/${normalizedOptions.projectRoot}`,\n },\n dependsOn: [\n {\n target: \"build\",\n },\n ],\n outputs: [\"{workspaceRoot}/dist/\" + normalizedOptions.projectRoot],\n },\n },\n });\n addFiles(tree, normalizedOptions, packageJsonLocally);\n // enforcing engine versions specified in package.json\n tree.write(\".npmrc\", \"engine-strict=true\");\n\n await formatFiles(tree);\n return () => {\n installPackagesTask(tree, true);\n\n // eslint-disable-next-line no-console\n console.log(\n \"🥳 Successfully created an Iris App - review the iris-app-manifest.ts and start adding app extensions!\"\n );\n };\n};\n\nexport default IrisAppGenerator;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dependencies.js","sourceRoot":"","sources":["../../../../../../../libs/iris-app-sdk/iris-app/src/generators/extend/dependencies.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEU,QAAA,eAAe,GAAG;IAC7B,YAAY,EAAE,QAAQ;IACtB,kBAAkB,EAAE,OAAO;CAC5B,CAAC;AAEW,QAAA,gBAAgB,GAAG;IAC9B,UAAU,EAAE,QAAQ;IACpB,wBAAwB,EAAE,QAAQ;IAClC,sBAAsB,EAAE,SAAS;IACjC,IAAI,EAAE,QAAQ;IACd,wBAAwB,EAAE,QAAQ;IAClC,qBAAqB,EAAE,QAAQ;IAC/B,iBAAiB,EAAE,QAAQ;IAC3B,SAAS,EAAE,QAAQ;CACpB,CAAC","sourcesContent":["/*\n * Use this file to maintain the version of single-spa and related dependencies.\n * Versions in here should be in sync with the versions in manager package.json.\n * If the test fails, update this file to reflect the version in manager package.json file.\n */\n\nexport const spaDependencies = {\n \"single-spa\": \"^5.9.5\",\n \"single-spa-react\": \"5.1.4\",\n};\n\nexport const testDependencies = {\n \"@nx/jest\": \"22.4.4\",\n \"@testing-library/react\": \"16.2.0\",\n \"@testing-library/dom\": \"^10.4.0\",\n jest: \"30.0.5\",\n \"jest-environment-jsdom\": \"30.0.5\",\n \"jest-transform-stub\": \"^2.0.0\",\n \"jest-fetch-mock\": \"^3.0.3\",\n \"ts-jest\": \"29.4.6\",\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../../libs/iris-app-sdk/iris-app/src/generators/extend/generator.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n addDependenciesToPackageJson,\n formatFiles,\n generateFiles,\n getWorkspaceLayout,\n installPackagesTask,\n joinPathFragments,\n names,\n offsetFromRoot,\n Tree,\n updateJson,\n} from \"@nx/devkit\";\nimport { Linter } from \"@nx/eslint\";\nimport { getRootTsConfigPathInTree } from \"@nx/js\";\nimport { getNpmScope } from \"@nx/js/src/utils/package-json/get-npm-scope\";\nimport { libraryGenerator } from \"@nx/react\";\nimport { Schema } from \"@nx/react/src/generators/library/schema\";\nimport { nonUiExtensionTypes, serverSideExtensionTypes } from \"@trackunit/iris-app-api\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport { camelCase } from \"string-ts\";\nimport { Project, SyntaxKind, VariableDeclaration } from \"ts-morph\";\nimport { addRequireStatement, addSpreadAssignment } from \"../../utils/ast/astUtils\";\nimport { spaDependencies, testDependencies } from \"./dependencies\";\nimport { IrisAppExtensionGeneratorSchema } from \"./schema\";\n\ninterface NormalizedSchema extends IrisAppExtensionGeneratorSchema {\n projectName: string;\n projectRoot: string;\n projectDirectory: string;\n projectCamelcase: string;\n importPath: string;\n sourceRoot: string;\n dependencyDefinitionFile: string;\n}\n\nfunction normalizeOptions(tree: Tree, options: IrisAppExtensionGeneratorSchema): NormalizedSchema {\n const name = names(options.name).fileName;\n const projectDirectory = options.directory ? `${names(options.directory).fileName}/${name}` : name;\n const projectName = projectDirectory.replace(new RegExp(\"/\", \"g\"), \"-\");\n const projectCamelcase = camelCase(projectName);\n const wsLayout = getWorkspaceLayout(tree);\n const projectRoot = `${wsLayout.libsDir}/${projectDirectory}`;\n const sourceRoot = `${wsLayout.libsDir}/${projectDirectory}/src`;\n const dependencyDefinitionFile = `${wsLayout.libsDir}/${projectDirectory}/package.json`;\n\n const npmScope = getNpmScope(tree);\n if (!npmScope) {\n throw new Error(\"Could not find npm scope in package.json\");\n }\n const importPath = `@${npmScope}/${projectName}`;\n\n return {\n ...options,\n projectName,\n projectRoot,\n projectDirectory,\n projectCamelcase,\n importPath,\n sourceRoot,\n dependencyDefinitionFile,\n };\n}\n\n/**\n * Ensures that jest.preset.js exists and includes the required @trackunit/react-test-setup preset.\n * If the file doesn't exist, creates it. If it exists but doesn't include the preset, updates it.\n */\nexport function ensureJestPresetConfiguration(tree: Tree, templateOptions?: object): void {\n const jestPresetPath = \"jest.preset.js\";\n\n if (!tree.exists(jestPresetPath)) {\n // File doesn't exist, generate it using the template\n generateFiles(tree, path.join(__dirname, \"files\", \"preset\"), \"/\", templateOptions || {});\n return;\n }\n\n // File exists, use AST utilities for reliable manipulation\n let currentContent = tree.read(jestPresetPath, \"utf-8\");\n if (!currentContent) {\n throw new Error(`Could not read ${jestPresetPath}`);\n }\n\n // Extract variable name from existing import if it exists\n let presetVariableName = \"irisPreset\"; // default name\n const existingImportMatch = currentContent.match(\n /const\\s+(\\w+)\\s*=\\s*require\\([\"']@trackunit\\/react-test-setup\\/preset[\"']\\)/\n );\n if (existingImportMatch && existingImportMatch[1]) {\n presetVariableName = existingImportMatch[1];\n }\n\n // Add the require statement if it doesn't exist\n currentContent = addRequireStatement(currentContent, presetVariableName, \"@trackunit/react-test-setup/preset\");\n\n // Add the spread assignment to the module.exports object\n currentContent = addSpreadAssignment(currentContent, presetVariableName);\n\n // Write the updated content back to the tree\n tree.write(jestPresetPath, currentContent);\n}\n\n/**\n * Iris App Extension Generator.\n *\n * @param tree the nx tree\n * @param options the generator options\n * @returns { Promise<void> } void\n */\nexport const IrisAppExtensionGenerator = async function (tree: Tree, options: IrisAppExtensionGeneratorSchema) {\n const adjustedOptions = await updateAppName(tree, options);\n\n const normalizedOptions = normalizeOptions(tree, adjustedOptions);\n\n const templateOptions = {\n ...normalizedOptions,\n ...names(normalizedOptions.name),\n offsetFromRoot: offsetFromRoot(normalizedOptions.projectRoot),\n template: \"\",\n };\n const irisAppExtensionType = normalizedOptions.type;\n\n if (!tree.exists(`${getWorkspaceLayout(tree).appsDir}/${normalizedOptions.app}`)) {\n throw new Error(\n `The app does not exist: ${getWorkspaceLayout(tree).appsDir}/${\n normalizedOptions.app\n } make sure you enter the right app name`\n );\n }\n\n const manifestPath = `${getWorkspaceLayout(tree).appsDir}/${normalizedOptions.app}/iris-app-manifest.ts`;\n if (!tree.exists(manifestPath)) {\n throw new Error(\n `The app does not have an iris-app-manifest.ts: ${manifestPath} make sure you enter the right app name, which has an iris-app-manifest.ts`\n );\n }\n\n if (normalizedOptions.updatePackageJson) {\n addDependenciesToPackageJson(\n tree,\n {},\n {\n ...spaDependencies,\n ...testDependencies,\n }\n );\n }\n\n const schema: Schema = {\n name: normalizedOptions.projectName,\n style: \"none\",\n skipFormat: false,\n strict: true,\n unitTestRunner: \"jest\",\n linter: Linter.EsLint,\n routing: false,\n directory: normalizedOptions.projectRoot,\n skipTsConfig: false,\n skipPackageJson: true,\n };\n\n await libraryGenerator(tree, schema);\n\n generateFiles(\n tree,\n path.join(__dirname, \"files\", irisAppExtensionType),\n normalizedOptions.projectRoot,\n templateOptions\n );\n\n if (!nonUiExtensionTypes.includes(irisAppExtensionType)) {\n generateFiles(tree, path.join(__dirname, \"files\", \"react-app\"), normalizedOptions.projectRoot, templateOptions);\n if (normalizedOptions.extendJestPreset) {\n ensureJestPresetConfiguration(tree, templateOptions);\n }\n }\n\n const rootTsConfigPath = getRootTsConfigPathInTree(tree);\n if (!rootTsConfigPath) {\n throw new Error(\"Could not find root tsconfig.json\");\n }\n updateJson(tree, rootTsConfigPath, tsConfigBase => {\n // For server side extension types, we need to add deno types to the tsconfig and make Typescript accept Deno import syntax\n if (serverSideExtensionTypes.includes(irisAppExtensionType)) {\n tsConfigBase.compilerOptions = {\n ...tsConfigBase.compilerOptions,\n types: [\"node\"],\n esModuleInterop: true,\n };\n }\n\n tsConfigBase.compilerOptions.paths[normalizedOptions.importPath] = [\n path.join(normalizedOptions.projectRoot, \"extension-manifest.ts\"),\n ];\n return tsConfigBase;\n });\n\n // Add working serve target to the project.json for DENO extensions\n if (serverSideExtensionTypes.includes(irisAppExtensionType)) {\n updateJson(tree, joinPathFragments(normalizedOptions.projectRoot, \"project.json\"), projectJson => {\n projectJson.targets.serve = {\n executor: \"@nx/js:node\",\n options: {\n buildTarget: `${normalizedOptions.projectName}:build:development`,\n inspect: true,\n },\n configurations: {\n breakOnStart: {\n inspect: \"inspect-brk\",\n },\n },\n };\n projectJson.targets.build = {\n executor: \"@nx/esbuild:esbuild\",\n outputs: [\"{options.outputPath}\"],\n defaultConfiguration: \"production\",\n options: {\n platform: \"node\",\n outputPath: `dist/${normalizedOptions.projectRoot}`,\n format: [\"cjs\"],\n bundle: true,\n thirdParty: true,\n external: [],\n main: `${normalizedOptions.sourceRoot}/index.ts`,\n tsConfig: `libs/${normalizedOptions.projectDirectory}/tsconfig.lib.json`,\n esbuildOptions: {\n sourcemap: true,\n outExtension: {\n \".js\": \".js\",\n },\n },\n },\n configurations: {\n development: {\n main: `${normalizedOptions.sourceRoot}/local-serve.ts`,\n },\n production: {\n esbuildOptions: {\n sourcemap: false,\n outExtension: {\n \".js\": \".js\",\n },\n },\n },\n },\n };\n return projectJson;\n });\n }\n\n //TODO: Change the following to update the manifest in the virtual Tree - not on the file system.\n const project = new Project({\n tsConfigFilePath: `${getWorkspaceLayout(tree).appsDir}/${normalizedOptions.app}/tsconfig.app.json`,\n });\n\n const manifest = project.getSourceFileOrThrow(manifestPath);\n\n manifest.addImportDeclaration({\n moduleSpecifier: normalizedOptions.importPath,\n defaultImport: normalizedOptions.projectCamelcase,\n });\n\n // Get the default export symbol from the manifest\n const defaultExportSymbol = manifest.getDefaultExportSymbolOrThrow();\n\n // Get the aliased symbol if the default export is an alias\n const aliasedSymbol = defaultExportSymbol.getAliasedSymbol() || defaultExportSymbol;\n\n // Get the declaration of the aliased symbol\n const declaration = aliasedSymbol.getDeclarations()[0];\n\n if (!VariableDeclaration.isVariableDeclaration(declaration)) {\n throw new Error(\"Expected variable declaration\");\n }\n const irisAppManifestObject = declaration.getInitializer()?.asKindOrThrow(SyntaxKind.ObjectLiteralExpression);\n\n if (!irisAppManifestObject) {\n throw new Error(`irisAppManifest not exported from the file: ${manifestPath}`);\n }\n // Find the extensions property within the irisAppManifest object\n const extensionsProperty = irisAppManifestObject.getPropertyOrThrow(\"extensions\");\n\n if (extensionsProperty.getKind() === SyntaxKind.PropertyAssignment) {\n const extensionsArray = extensionsProperty.getFirstChildByKindOrThrow(SyntaxKind.ArrayLiteralExpression);\n extensionsArray.addElement(`${normalizedOptions.projectCamelcase}`);\n }\n\n await manifest.save();\n\n if (!serverSideExtensionTypes.includes(irisAppExtensionType)) {\n tree.delete(joinPathFragments(normalizedOptions.projectRoot, \"src\", \"index.ts\"));\n }\n\n updateJson(tree, joinPathFragments(normalizedOptions.projectRoot, \"tsconfig.spec.json\"), tsConfigSpec => {\n // extension-manifest.ts is a build time file, so we only need to include it in the spec file for type/lint checking\n tsConfigSpec.include = [...tsConfigSpec.include, \"**/jest.setup.ts*\", \"extension-manifest.ts\"];\n return tsConfigSpec;\n });\n\n await formatFiles(tree);\n installPackagesTask(tree, true);\n return () => {\n // eslint-disable-next-line no-console\n console.log(\"🥳 Successfully created an app extensions and it is already added to the Iris App!\");\n };\n};\nconst updateAppName = async (tree: Tree, options: IrisAppExtensionGeneratorSchema) => {\n if (!options.app) {\n const folders = fs\n .readdirSync(getWorkspaceLayout(tree).appsDir, { withFileTypes: true })\n .filter(item => item.isDirectory());\n\n const tileApps: Array<string> = [];\n\n folders.forEach(folder => {\n const irisAppManifest = fs\n .readdirSync(`${getWorkspaceLayout(tree).appsDir}/${folder.name}`, { withFileTypes: true })\n .find(item => item.name === \"iris-app-manifest.ts\");\n\n if (irisAppManifest) {\n tileApps.push(folder.name);\n } else {\n const subFolders = fs\n .readdirSync(path.join(getWorkspaceLayout(tree).appsDir, folder.name), { withFileTypes: true })\n .filter(item => item.isDirectory());\n subFolders.forEach(subFolder => {\n const subDirIrisAppManifest = fs\n .readdirSync(`${getWorkspaceLayout(tree).appsDir}/${folder.name}/${subFolder.name}`, {\n withFileTypes: true,\n })\n .find(item => item.name === \"iris-app-manifest.ts\");\n\n if (subDirIrisAppManifest) {\n tileApps.push(path.join(folder.name, subFolder.name));\n }\n });\n }\n });\n\n if (tileApps.length === 1) {\n options.app = tileApps[0] || \"<Missing iris app name>\";\n } else if (tileApps.length === 0) {\n throw new Error(\"Please add an iris-app using: nx g @trackunit/iris-app:create \");\n } else {\n // Dynamic import to avoid loading ESM module at test time when not needed\n const { autocomplete, isCancel, cancel } = await import(\"@clack/prompts\");\n\n const selectedApp = await autocomplete({\n message: \"Select the iris app that this extension should belong to (type to filter):\",\n options: tileApps.map(item => ({ value: item, label: item })),\n maxItems: 15,\n });\n\n if (isCancel(selectedApp)) {\n cancel(\"Operation cancelled.\");\n process.exit(0);\n }\n\n options.app = selectedApp;\n }\n }\n return options;\n};\n\nexport default IrisAppExtensionGenerator;\n"]}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: browser-testing
|
|
3
|
+
description: Use when testing IrisX Apps in browser, extension not appearing, dev mode toggle issues, or verifying code changes in Trackunit Manager.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Browser Testing for IrisX Apps
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
IrisX Apps run inside Trackunit Manager, not on localhost. Test at `https://new.manager.trackunit.com/goto/iris-app-dev` with "Use Local Apps" enabled.
|
|
11
|
+
|
|
12
|
+
## Chrome DevTools MCP Required
|
|
13
|
+
|
|
14
|
+
**IrisX Apps render inside iFrames.** Standard browser automation tools cannot interact with iFrame content. You **MUST** use Chrome DevTools MCP for browser testing.
|
|
15
|
+
|
|
16
|
+
### Check Chrome DevTools MCP Availability
|
|
17
|
+
|
|
18
|
+
Before browser testing, verify the MCP is available:
|
|
19
|
+
|
|
20
|
+
1. Check if `chrome-devtools` MCP server is enabled in Cursor settings
|
|
21
|
+
2. Try listing pages: use the `list_pages` tool from `user-chrome-devtools` server
|
|
22
|
+
3. If tools are not available, the MCP needs to be configured
|
|
23
|
+
|
|
24
|
+
### Setup Chrome DevTools MCP
|
|
25
|
+
|
|
26
|
+
If Chrome DevTools MCP is not available:
|
|
27
|
+
|
|
28
|
+
1. **Install the MCP server** - Guide the user to install `chrome-devtools-mcp`
|
|
29
|
+
2. **Configure in Cursor** - Add the server to `.cursor/mcp.json`:
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"mcpServers": {
|
|
33
|
+
"chrome-devtools": {
|
|
34
|
+
"command": "npx",
|
|
35
|
+
"args": ["-y", "chrome-devtools-mcp@latest"]
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
3. **Restart Cursor** to load the new MCP server
|
|
41
|
+
4. **Launch Chrome with debugging** - Chrome must be started with remote debugging enabled (the MCP handles this)
|
|
42
|
+
|
|
43
|
+
### Why Chrome DevTools?
|
|
44
|
+
|
|
45
|
+
| Standard Browser Tools | Chrome DevTools MCP |
|
|
46
|
+
|------------------------|---------------------|
|
|
47
|
+
| Cannot access iFrame content | Full iFrame support via CDP |
|
|
48
|
+
| Limited to top-level DOM | Access nested contexts |
|
|
49
|
+
| Screenshots miss iFrame content | Captures complete page |
|
|
50
|
+
| Cannot interact with extensions | Full extension interaction |
|
|
51
|
+
|
|
52
|
+
## When to Use
|
|
53
|
+
|
|
54
|
+
- Testing extension after code changes
|
|
55
|
+
- Extension not appearing or showing blank
|
|
56
|
+
- Enabling local development mode
|
|
57
|
+
- Debugging GraphQL/API errors in browser
|
|
58
|
+
- Verifying UI renders correctly
|
|
59
|
+
|
|
60
|
+
**Not for:** Unit tests, linting, or type checking (use NX commands).
|
|
61
|
+
|
|
62
|
+
## Quick Reference
|
|
63
|
+
|
|
64
|
+
### Setup Steps
|
|
65
|
+
|
|
66
|
+
1. Navigate to `https://new.manager.trackunit.com/goto/iris-app-dev`
|
|
67
|
+
2. Wait for user login (2-4 minutes)
|
|
68
|
+
3. Enable "Use Local Apps" toggle (main content area, not sidebar)
|
|
69
|
+
4. Navigate to extension based on type
|
|
70
|
+
|
|
71
|
+
### Navigate to Extension
|
|
72
|
+
|
|
73
|
+
Based on extension type:
|
|
74
|
+
|
|
75
|
+
| Extension Type | Navigation |
|
|
76
|
+
|----------------|------------|
|
|
77
|
+
| `FLEET_EXTENSION` | Main menu → App name |
|
|
78
|
+
| `ASSET_HOME_EXTENSION` | Assets → Open any asset → Extension tab |
|
|
79
|
+
| `SITE_HOME_EXTENSION` | Sites → Open any site → Extension tab |
|
|
80
|
+
| `WIDGET_EXTENSION` | Dashboard → Add Widget → Find widget |
|
|
81
|
+
|
|
82
|
+
## Testing After Code Changes
|
|
83
|
+
|
|
84
|
+
### Reload Strategy
|
|
85
|
+
|
|
86
|
+
After making code changes:
|
|
87
|
+
|
|
88
|
+
**1. Check Lints First (Zero Tolerance):**
|
|
89
|
+
```
|
|
90
|
+
- Run read_lints on modified files
|
|
91
|
+
- Fix ALL errors before testing in browser
|
|
92
|
+
- Do not proceed with any TypeScript or linter errors
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**2. Reload Browser:**
|
|
96
|
+
|
|
97
|
+
The dev server hot-reloads, but sometimes a full page refresh is needed:
|
|
98
|
+
|
|
99
|
+
| Option | When to Use | How |
|
|
100
|
+
|--------|-------------|-----|
|
|
101
|
+
| Wait for Hot Reload | First attempt | Wait 2-3 seconds |
|
|
102
|
+
| Soft Refresh | Changes don't appear | `Command+R` (Mac) or `Ctrl+R` (Windows) |
|
|
103
|
+
| Hard Refresh | Soft refresh fails | `Command+Shift+R` (Mac) or `Ctrl+Shift+R` (Windows) |
|
|
104
|
+
|
|
105
|
+
**3. Manifest Changes Require Re-Serve:**
|
|
106
|
+
|
|
107
|
+
If you modified `iris-app-manifest.ts` (scopes, CSP headers, metadata):
|
|
108
|
+
- Browser reload is NOT enough
|
|
109
|
+
- Stop the dev server (`Ctrl+C`)
|
|
110
|
+
- Re-run: `npx nx run [app-name]:serve`
|
|
111
|
+
- Wait for server to restart
|
|
112
|
+
- Then reload browser
|
|
113
|
+
|
|
114
|
+
### Verification Checklist
|
|
115
|
+
|
|
116
|
+
After each reload:
|
|
117
|
+
|
|
118
|
+
1. Take browser snapshot
|
|
119
|
+
2. Look for extension content
|
|
120
|
+
3. Check if blank/empty → may need hard refresh
|
|
121
|
+
4. Verify expected UI elements are present
|
|
122
|
+
5. Check console for errors
|
|
123
|
+
6. Check network requests for GraphQL/API issues
|
|
124
|
+
|
|
125
|
+
## Troubleshooting
|
|
126
|
+
|
|
127
|
+
### Extension Shows Blank After Changes
|
|
128
|
+
|
|
129
|
+
1. Try hard refresh (`Command+Shift+R`)
|
|
130
|
+
2. Check browser console for errors
|
|
131
|
+
3. Check if dev server is still running
|
|
132
|
+
4. Verify file saved correctly
|
|
133
|
+
5. Check for TypeScript compilation errors
|
|
134
|
+
6. Navigate away and back to extension
|
|
135
|
+
|
|
136
|
+
### "Use Local Apps" Toggle Not Found
|
|
137
|
+
|
|
138
|
+
1. Verify user is logged in
|
|
139
|
+
2. Navigate directly to `https://new.manager.trackunit.com/goto/iris-app-dev`
|
|
140
|
+
3. Wait for page to fully load (redirects to Developer Settings)
|
|
141
|
+
4. Take snapshot to see what's visible
|
|
142
|
+
5. Toggle is in the main content area, not the sidebar
|
|
143
|
+
|
|
144
|
+
### Extension Not Appearing
|
|
145
|
+
|
|
146
|
+
1. Verify dev server is running
|
|
147
|
+
2. Check manifest has correct extension type
|
|
148
|
+
3. If changed `iris-app-manifest.ts` → re-serve the app
|
|
149
|
+
4. Hard refresh browser
|
|
150
|
+
5. Disable and re-enable "Use Local Apps"
|
|
151
|
+
6. Check browser console for loading errors
|
|
152
|
+
|
|
153
|
+
### GraphQL/API Errors
|
|
154
|
+
|
|
155
|
+
1. Use browser network tab to find GraphQL requests
|
|
156
|
+
2. Inspect response body for "errors" array (GraphQL returns 200 even with errors)
|
|
157
|
+
3. Common fixes:
|
|
158
|
+
- Missing scopes → Add to `iris-app-manifest.ts` scopes array
|
|
159
|
+
- CSP violations → Add domain to `cspHeader` in manifest
|
|
160
|
+
- Auth issues → Deploy app to enable new scopes
|
|
161
|
+
|
|
162
|
+
## Workflow Checklist
|
|
163
|
+
|
|
164
|
+
### After Every Code Change:
|
|
165
|
+
|
|
166
|
+
1. ✅ Check lints (zero tolerance)
|
|
167
|
+
2. ✅ Fix all errors
|
|
168
|
+
3. ✅ Wait 2-3 seconds for hot reload
|
|
169
|
+
4. ✅ Refresh browser if needed
|
|
170
|
+
5. ✅ Take snapshot
|
|
171
|
+
6. ✅ Verify changes visible
|
|
172
|
+
7. ✅ Check console for errors
|
|
173
|
+
8. ✅ Check network tab if using APIs
|
|
174
|
+
|
|
175
|
+
### Before Moving to Next Feature:
|
|
176
|
+
|
|
177
|
+
1. ✅ Current feature fully working in browser
|
|
178
|
+
2. ✅ Zero linter/TypeScript errors
|
|
179
|
+
3. ✅ Zero browser console errors
|
|
180
|
+
4. ✅ All network requests successful
|
|
181
|
+
5. ✅ Screenshot of working feature
|
|
182
|
+
|
|
183
|
+
## Common Mistakes
|
|
184
|
+
|
|
185
|
+
| Mistake | Fix |
|
|
186
|
+
|---------|-----|
|
|
187
|
+
| Using default browser automation | Extensions render in iFrames; use Chrome DevTools MCP |
|
|
188
|
+
| Testing on localhost | Use `https://new.manager.trackunit.com/goto/iris-app-dev` |
|
|
189
|
+
| Skipping lint check before browser | Always run `read_lints` first |
|
|
190
|
+
| Not enabling "Use Local Apps" | Toggle is in main content area, not sidebar |
|
|
191
|
+
| Changed manifest without re-serve | Stop dev server and restart |
|
|
192
|
+
| Moving to next feature before verifying | Confirm current feature works in browser first |
|
|
193
|
+
| Chrome DevTools MCP not configured | Help user install and configure the MCP server |
|