@trackunit/iris-app 2.16.4-alpha-1872e1df7fb.0 → 2.16.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. package/CHANGELOG.md +160 -0
  2. package/package.json +6 -6
  3. package/src/executors/submit/executor.js +15 -1
  4. package/src/generators/ai-agent-sync/README.md +4 -3
  5. package/src/generators/ai-agent-sync/generator.d.ts +1 -1
  6. package/src/generators/ai-agent-sync/generator.js +48 -3
  7. package/src/generators/ai-agent-sync/legacy-claude-md/v1.md +1 -0
  8. package/src/generators/ai-agent-sync/legacy-claude-md/v2.md +13 -0
  9. package/src/generators/ai-agent-sync/legacy-claude-md/v3.md +17 -0
  10. package/src/generators/ai-agent-sync/legacy-claude-md/v4.md +17 -0
  11. package/src/generators/extend/files/non-ui-test/extension-manifest.spec.ts__template__ +1 -1
  12. package/src/generators/extend/files/react-app/src/routeTree.tsx__template__ +4 -3
  13. package/src/generators/extend/generator.js +0 -14
  14. package/src/generators/extend/schema.d.ts +1 -2
  15. package/src/generators/extend/schema.json +1 -2
  16. package/src/generators/preset/root-files/AGENTS.md +16 -0
  17. package/src/generators/extend/files/AI_TOOLS_EXTENSION/.env.example__template__ +0 -9
  18. package/src/generators/extend/files/AI_TOOLS_EXTENSION/extension-manifest.ts__template__ +0 -16
  19. package/src/generators/extend/files/AI_TOOLS_EXTENSION/package.json__template__ +0 -10
  20. package/src/generators/extend/files/AI_TOOLS_EXTENSION/src/index.ts__template__ +0 -9
  21. package/src/generators/extend/files/AI_TOOLS_EXTENSION/src/local-serve.ts__template__ +0 -11
  22. package/src/generators/extend/files/AI_TOOLS_EXTENSION/src/tools.ts__template__ +0 -16
  23. /package/src/generators/{preset/root-files/CLAUDE.md → ai-agent-sync/legacy-claude-md/v5.md} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,3 +1,163 @@
1
+ ## 2.16.5 (2026-11-05)
2
+
3
+ ### 🩹 Fixes
4
+
5
+ - **deps:** bump node-vault to 0.10.10 for Snyk uri-js high ([#27152](https://github.com/Trackunit/manager/pull/27152))
6
+
7
+ ### 🧱 Updated Dependencies
8
+
9
+ - Updated iris-app-build-utilities to 3.0.20
10
+ - Updated iris-app-api to 2.13.8
11
+ - Updated react-vite-test-setup to 0.0.206
12
+ - Updated css-classname-utils to 0.0.114
13
+ - Updated react-graphql-tools to 1.23.37
14
+ - Updated shared-utils to 1.22.33
15
+
16
+ ### ❤️ Thank You
17
+
18
+ - kla-trackunit
19
+ - Mikkel Thorbjørn Andersen @mta-trackunit
20
+ - mta
21
+
22
+ ## 2.16.4 (2026-11-05)
23
+
24
+ ### 🧱 Updated Dependencies
25
+
26
+ - Updated iris-app-build-utilities to 3.0.19
27
+ - Updated iris-app-api to 2.13.7
28
+ - Updated react-vite-test-setup to 0.0.205
29
+ - Updated css-classname-utils to 0.0.113
30
+ - Updated react-graphql-tools to 1.23.36
31
+ - Updated shared-utils to 1.22.32
32
+
33
+ ## 2.16.3 (2026-11-04)
34
+
35
+ ### 🧱 Updated Dependencies
36
+
37
+ - Updated iris-app-build-utilities to 3.0.18
38
+ - Updated iris-app-api to 2.13.6
39
+ - Updated react-vite-test-setup to 0.0.204
40
+ - Updated css-classname-utils to 0.0.112
41
+ - Updated react-graphql-tools to 1.23.35
42
+ - Updated shared-utils to 1.22.31
43
+
44
+ ## 2.16.2 (2026-11-04)
45
+
46
+ ### 🧱 Updated Dependencies
47
+
48
+ - Updated iris-app-build-utilities to 3.0.17
49
+ - Updated iris-app-api to 2.13.5
50
+ - Updated react-vite-test-setup to 0.0.203
51
+ - Updated css-classname-utils to 0.0.111
52
+ - Updated react-graphql-tools to 1.23.34
53
+ - Updated shared-utils to 1.22.30
54
+
55
+ ## 2.16.1 (2026-11-04)
56
+
57
+ ### 🧱 Updated Dependencies
58
+
59
+ - Updated iris-app-build-utilities to 3.0.16
60
+ - Updated iris-app-api to 2.13.4
61
+ - Updated react-vite-test-setup to 0.0.202
62
+ - Updated css-classname-utils to 0.0.110
63
+ - Updated react-graphql-tools to 1.23.33
64
+ - Updated shared-utils to 1.22.29
65
+
66
+ ## 2.16.0 (2026-11-04)
67
+
68
+ ### 🚀 Features
69
+
70
+ - **iris-app-sdk:** guide apps to lazy pages for AI navigation and follow getParentRoute ([#27279](https://github.com/Trackunit/manager/pull/27279))
71
+ - **iris-app:** generate AGENTS.md only, no CLAUDE.md ([#27348](https://github.com/Trackunit/manager/pull/27348))
72
+
73
+ ### 🧱 Updated Dependencies
74
+
75
+ - Updated iris-app-build-utilities to 3.0.15
76
+ - Updated iris-app-api to 2.13.3
77
+ - Updated react-vite-test-setup to 0.0.201
78
+ - Updated css-classname-utils to 0.0.109
79
+ - Updated react-graphql-tools to 1.23.32
80
+ - Updated shared-utils to 1.22.28
81
+
82
+ ### ❤️ Thank You
83
+
84
+ - Kasper Laursen @ghost-of-kla-trackunit
85
+ - Ulrik Jørgensen @ujo-trackunit
86
+
87
+ ## 2.15.16 (2026-11-04)
88
+
89
+ ### 🧱 Updated Dependencies
90
+
91
+ - Updated iris-app-build-utilities to 3.0.14
92
+ - Updated iris-app-api to 2.13.2
93
+ - Updated react-vite-test-setup to 0.0.200
94
+ - Updated css-classname-utils to 0.0.108
95
+ - Updated react-graphql-tools to 1.23.31
96
+ - Updated shared-utils to 1.22.27
97
+
98
+ ## 2.15.15 (2026-11-03)
99
+
100
+ ### 🩹 Fixes
101
+
102
+ - **iris-app:** retry submit when iris-app-sdk-server's upstream fetch fails ([#27291](https://github.com/Trackunit/manager/pull/27291))
103
+
104
+ ### ❤️ Thank You
105
+
106
+ - mta
107
+ - Nick Lediet
108
+
109
+ ## 2.15.14 (2026-11-03)
110
+
111
+ ### 🧱 Updated Dependencies
112
+
113
+ - Updated iris-app-build-utilities to 3.0.13
114
+ - Updated iris-app-api to 2.13.1
115
+ - Updated react-vite-test-setup to 0.0.199
116
+ - Updated css-classname-utils to 0.0.107
117
+ - Updated react-graphql-tools to 1.23.30
118
+ - Updated shared-utils to 1.22.26
119
+
120
+ ## 2.15.13 (2026-11-03)
121
+
122
+ ### 🧱 Updated Dependencies
123
+
124
+ - Updated iris-app-build-utilities to 3.0.12
125
+ - Updated iris-app-api to 2.13.0
126
+ - Updated react-graphql-tools to 1.23.29
127
+
128
+ ## 2.15.12 (2026-11-03)
129
+
130
+ ### 🧱 Updated Dependencies
131
+
132
+ - Updated iris-app-build-utilities to 3.0.11
133
+ - Updated iris-app-api to 2.12.28
134
+ - Updated react-vite-test-setup to 0.0.198
135
+ - Updated css-classname-utils to 0.0.106
136
+ - Updated react-graphql-tools to 1.23.28
137
+ - Updated shared-utils to 1.22.25
138
+
139
+ ## 2.15.11 (2026-11-03)
140
+
141
+ ### 🧱 Updated Dependencies
142
+
143
+ - Updated iris-app-build-utilities to 3.0.10
144
+ - Updated iris-app-api to 2.12.27
145
+ - Updated react-vite-test-setup to 0.0.197
146
+ - Updated css-classname-utils to 0.0.105
147
+ - Updated react-graphql-tools to 1.23.27
148
+ - Updated shared-utils to 1.22.24
149
+
150
+ ## 2.15.10 (2026-11-03)
151
+
152
+ ### 🧱 Updated Dependencies
153
+
154
+ - Updated iris-app-build-utilities to 3.0.9
155
+ - Updated iris-app-api to 2.12.26
156
+ - Updated react-vite-test-setup to 0.0.196
157
+ - Updated css-classname-utils to 0.0.104
158
+ - Updated react-graphql-tools to 1.23.26
159
+ - Updated shared-utils to 1.22.23
160
+
1
161
  ## 2.15.9 (2026-11-02)
2
162
 
3
163
  ### 🧱 Updated Dependencies
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/iris-app",
3
- "version": "2.16.4-alpha-1872e1df7fb.0",
3
+ "version": "2.16.5",
4
4
  "license": "SEE LICENSE IN LICENSE.txt",
5
5
  "main": "src/index.js",
6
6
  "generators": "./generators.json",
@@ -10,7 +10,7 @@
10
10
  "node": ">=24.x"
11
11
  },
12
12
  "dependencies": {
13
- "@trackunit/css-classname-utils": "0.0.113-alpha-1872e1df7fb.0",
13
+ "@trackunit/css-classname-utils": "0.0.114",
14
14
  "@typescript-eslint/types": "8.71.2",
15
15
  "@typescript-eslint/typescript-estree": "8.71.2",
16
16
  "pacote": "^21.5.1",
@@ -26,10 +26,10 @@
26
26
  "@nx/react": "23.3.0",
27
27
  "@npmcli/arborist": "^9.1.9",
28
28
  "win-ca": "^3.5.1",
29
- "@trackunit/iris-app-build-utilities": "3.0.19-alpha-1872e1df7fb.0",
30
- "@trackunit/react-graphql-tools": "1.23.36-alpha-1872e1df7fb.0",
31
- "@trackunit/shared-utils": "1.22.32-alpha-1872e1df7fb.0",
32
- "@trackunit/iris-app-api": "2.13.7-alpha-1872e1df7fb.0",
29
+ "@trackunit/iris-app-build-utilities": "3.0.20",
30
+ "@trackunit/react-graphql-tools": "1.23.37",
31
+ "@trackunit/shared-utils": "1.22.33",
32
+ "@trackunit/iris-app-api": "2.13.8",
33
33
  "tslib": "^2.6.2",
34
34
  "@clack/prompts": "^1.8.1",
35
35
  "@nx/devkit": "23.3.0",
@@ -90,6 +90,20 @@ function isRetryableError(statusCode, code, type) {
90
90
  }
91
91
  return RETRYABLE_TRANSPORT_CODES.has(code) || (code === "FETCH_ERROR" && type === "request-timeout");
92
92
  }
93
+ /**
94
+ * Older iris-app-sdk-server releases answer a failed outbound fetch of their own with
95
+ * 400 `{ error: "fetch failed" }`, which npm-registry-fetch appends to the message as " - fetch failed".
96
+ * That is a transient server-side failure, not a rejected package.
97
+ *
98
+ * @param {NpmGeneralError} error The failed upload attempt.
99
+ * @returns {boolean} Whether the attempt should be retried.
100
+ */
101
+ function isRetryableUploadError(error) {
102
+ if (error.statusCode === 400 && error.message.includes(" - fetch failed.")) {
103
+ return true;
104
+ }
105
+ return isRetryableError(error.statusCode, error.code, error.type);
106
+ }
93
107
  function isRetryableApproveError(statusCode, code, type) {
94
108
  // Same as isRetryableError but also accept 404 for approvals.
95
109
  // 404 can happen spuriously on approval
@@ -153,7 +167,7 @@ async function doUploadAppWithRetry(accessToken, manifest, tarData, settings, re
153
167
  console.error("❌ Unable to ship app package. Got error from Iris App SDK repository.", e);
154
168
  return { success: false };
155
169
  }
156
- if (!isRetryableError(e.statusCode, e.code, e.type)) {
170
+ if (!isRetryableUploadError(e)) {
157
171
  console.error("❌ Unable to ship app package.", e.message);
158
172
  return { success: false };
159
173
  }
@@ -1,6 +1,6 @@
1
1
  # AI Agent Sync Generator
2
2
 
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.
3
+ Syncs agent skills, AGENTS.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
 
@@ -13,8 +13,9 @@ nx g @trackunit/iris-app:ai-agent-sync
13
13
  - `.agents/skills/` - AI agent skills for the IrisX App SDK (editor-agnostic)
14
14
  - `.mcp.json` - project-scoped MCP configuration for coding agents
15
15
  - `.cursor/mcp.json` - Cursor MCP configuration
16
- - `AGENTS.md` - Workspace-level agent instructions (always applied)
17
- - `CLAUDE.md` - Claude-specific configuration (references AGENTS.md)
16
+ - `AGENTS.md` - Workspace-level agent instructions (always applied), read by Cursor and Claude Code
17
+
18
+ It also removes the `CLAUDE.md` that earlier SDK versions generated, since Claude Code reads `AGENTS.md` natively. Only an unmodified copy is removed (see `legacy-claude-md/`), and not while a `CLAUDE.local.md` or `.claude/CLAUDE.md` exists, since its `@AGENTS.md` import is then what loads `AGENTS.md`. A `CLAUDE.md` you wrote or edited is kept.
18
19
 
19
20
  ## Flow
20
21
 
@@ -1,7 +1,7 @@
1
1
  import { GeneratorCallback, Tree } from "@nx/devkit";
2
2
  import { AiAgentSyncGeneratorSchema } from "./schema";
3
3
  /**
4
- * Syncs Cursor skills, AGENTS.md, CLAUDE.md, and AI agent configuration files.
4
+ * Syncs Cursor skills, AGENTS.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<GeneratorCallback>;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.aiAgentSyncGenerator = aiAgentSyncGenerator;
4
4
  const tslib_1 = require("tslib");
5
5
  const devkit_1 = require("@nx/devkit");
6
+ const fs = tslib_1.__importStar(require("fs"));
6
7
  const devkit_exports_1 = require("nx/src/devkit-exports");
7
8
  const path = tslib_1.__importStar(require("path"));
8
9
  const semver = tslib_1.__importStar(require("semver"));
@@ -10,6 +11,9 @@ const get_package_manifest_1 = require("../utils/get-package-manifest");
10
11
  const link_claude_skills_1 = require("../utils/link-claude-skills");
11
12
  const IRIS_APP_PACKAGE = "@trackunit/iris-app";
12
13
  const MIGRATIONS_PACKAGE = "@trackunit/migrations";
14
+ const CLAUDE_MD = "CLAUDE.md";
15
+ const CLAUDE_MEMORY_FILES = [CLAUDE_MD, ".claude/CLAUDE.md", "CLAUDE.local.md"];
16
+ const LEGACY_CLAUDE_MD_DIR = path.join(__dirname, "legacy-claude-md");
13
17
  function getStringValue(obj, key) {
14
18
  if (typeof obj === "object" && obj !== null && key in obj) {
15
19
  const value = obj[key];
@@ -49,8 +53,48 @@ function upgradeInstructions() {
49
53
  ` ${pmc.exec} nx g ${MIGRATIONS_PACKAGE}:run-migrations`,
50
54
  ].join("\n");
51
55
  }
56
+ function normalizeWhitespace(content) {
57
+ return content.replace(/\s+/g, " ").trim();
58
+ }
59
+ /**
60
+ * Every CLAUDE.md template earlier SDK versions shipped, whitespace-normalized so a
61
+ * workspace formatter's line wrapping or line endings do not hide a match.
62
+ */
63
+ function readLegacyClaudeMdTemplates() {
64
+ return new Set(fs
65
+ .readdirSync(LEGACY_CLAUDE_MD_DIR)
66
+ .filter(file => file.endsWith(".md"))
67
+ .map(file => normalizeWhitespace(fs.readFileSync(path.join(LEGACY_CLAUDE_MD_DIR, file), "utf-8"))));
68
+ }
69
+ function importsAgentsMd(content) {
70
+ return /^@AGENTS\.md\s*$/m.test(content);
71
+ }
72
+ /**
73
+ * Earlier SDK versions generated a CLAUDE.md that imported AGENTS.md. Claude Code
74
+ * now reads AGENTS.md directly, so an unmodified copy of that file is removed. Any
75
+ * other CLAUDE.md is the user's and is kept, because AGENTS.md tells users they may
76
+ * add one.
77
+ *
78
+ * Claude Code skips AGENTS.md while any of its memory files exists, so the SDK copy
79
+ * is also kept when another one does: its import is then what loads AGENTS.md.
80
+ */
81
+ function removeSdkGeneratedClaudeMd(tree) {
82
+ const content = tree.read(CLAUDE_MD, "utf-8");
83
+ const otherMemoryFiles = CLAUDE_MEMORY_FILES.filter(file => file !== CLAUDE_MD && tree.exists(file));
84
+ if (content !== null &&
85
+ otherMemoryFiles.length === 0 &&
86
+ readLegacyClaudeMdTemplates().has(normalizeWhitespace(content))) {
87
+ tree.delete(CLAUDE_MD);
88
+ }
89
+ const presentMemoryFiles = CLAUDE_MEMORY_FILES.filter(file => tree.exists(file));
90
+ if (presentMemoryFiles.length > 0 &&
91
+ !presentMemoryFiles.some(file => importsAgentsMd(tree.read(file, "utf-8") ?? ""))) {
92
+ devkit_1.logger.warn(`[iris-app:ai-agent-sync] Claude Code skips AGENTS.md while ${presentMemoryFiles.join(", ")} exists. ` +
93
+ `Add an @AGENTS.md line to one of them or delete them.`);
94
+ }
95
+ }
52
96
  /**
53
- * Syncs Cursor skills, AGENTS.md, CLAUDE.md, and AI agent configuration files.
97
+ * Syncs Cursor skills, AGENTS.md, and AI agent configuration files.
54
98
  * Requires the SDK to be at the latest version before running.
55
99
  */
56
100
  async function aiAgentSyncGenerator(tree, options) {
@@ -69,7 +113,7 @@ async function aiAgentSyncGenerator(tree, options) {
69
113
  `Then run this generator again.`);
70
114
  }
71
115
  }
72
- // Clean up old .cursor files that were managed by previous versions.
116
+ // Clean up files that were managed by previous versions.
73
117
  const oldManagedFiles = [
74
118
  ".cursor/rules/irisx-app-sdk.mdc",
75
119
  ".cursor/rules/rules-index.mdc",
@@ -88,10 +132,11 @@ async function aiAgentSyncGenerator(tree, options) {
88
132
  tree.delete(file);
89
133
  }
90
134
  }
135
+ removeSdkGeneratedClaudeMd(tree);
91
136
  // Copy MCP configuration and agent skills shared with the preset generator.
92
137
  const managedFilesTemplatePath = path.join(__dirname, "../preset/files");
93
138
  (0, devkit_1.generateFiles)(tree, managedFilesTemplatePath, ".", {});
94
- // Copy AGENTS.md and CLAUDE.md to workspace root
139
+ // Copy AGENTS.md to workspace root
95
140
  const rootTemplatePath = path.join(__dirname, "../preset/root-files");
96
141
  (0, devkit_1.generateFiles)(tree, rootTemplatePath, ".", {});
97
142
  await (0, devkit_1.formatFiles)(tree);
@@ -0,0 +1,13 @@
1
+ @AGENTS.md
2
+
3
+ # Claude Code Users
4
+
5
+ Skills are in `.agents/skills/` (cross-tool compatible). Claude Code reads from `.claude/skills/`.
6
+
7
+ To enable skill discovery, create a symlink:
8
+
9
+ ```bash
10
+ ln -s .agents/skills .claude/skills
11
+ ```
12
+
13
+ Or read skills directly from `.agents/skills/[skill-name]/SKILL.md` when referenced in AGENTS.md.
@@ -0,0 +1,17 @@
1
+ @AGENTS.md
2
+
3
+ # IrisX App Workspace
4
+
5
+ This is an IrisX App project generated by the Trackunit SDK. Follow AGENTS.md for all development rules.
6
+
7
+ ## Skills
8
+
9
+ SDK-specific skills are located in `.agents/skills/`. When a skill is referenced in AGENTS.md, read it from `.agents/skills/[skill-name]/SKILL.md`.
10
+
11
+ If skills from `.agents/skills/` are not appearing in your available skills list, suggest the user symlink them for automatic discovery:
12
+
13
+ ```bash
14
+ ln -s .agents/skills .claude/skills
15
+ ```
16
+
17
+ Note: If the user already has a `.claude/skills` folder, they should symlink individual skills or the contents instead.
@@ -0,0 +1,17 @@
1
+ @AGENTS.md
2
+
3
+ # IrisX App Workspace
4
+
5
+ This is an IrisX App project generated by the Trackunit SDK. Follow AGENTS.md for all development rules.
6
+
7
+ ## Skills
8
+
9
+ SDK-specific skills live in `.agents/skills/`. The generator creates a `.claude/skills` symlink pointing at `../.agents/skills` so Claude Code auto-discovers them. When a skill is referenced in AGENTS.md, read it from `.agents/skills/[skill-name]/SKILL.md`.
10
+
11
+ If skills are not appearing in your available skills list, the symlink may be missing (for example on Windows without Developer Mode, or if a real `.claude/skills` directory existed first). Recreate it with:
12
+
13
+ ```bash
14
+ ln -s ../.agents/skills .claude/skills
15
+ ```
16
+
17
+ If `.claude/skills` already exists as a real directory, move its contents into `.agents/skills/` and delete it before running the command above.
@@ -5,7 +5,7 @@ describe("extension manifest", () => {
5
5
  expect(extensionManifest).toMatchObject({
6
6
  id: "<%= projectName %>",
7
7
  type: "<%= type %>",
8
- sourceRoot: "<% if (type === 'SERVERSIDE_API_EXTENSION' || type === 'AI_TOOLS_EXTENSION') { %>dist/<%= projectRoot %>/<% } else { %><%= sourceRoot %><% } %>",
8
+ sourceRoot: "<% if (type === 'SERVERSIDE_API_EXTENSION') { %>dist/<%= projectRoot %>/<% } else { %><%= sourceRoot %><% } %>",
9
9
  });
10
10
  });
11
11
  });
@@ -1,8 +1,9 @@
1
- import { Navigate, createRootRoute, createRoute } from "@tanstack/react-router";
2
- import { App } from "./app";
1
+ import { Navigate, createRootRoute, createRoute, lazyRouteComponent } from "@tanstack/react-router";
3
2
 
3
+ // Pages are loaded lazily because the extension manifest imports this tree in
4
+ // Node at build time, where a page that needs a browser would fail the build.
4
5
  const rootRoute = createRootRoute({
5
- component: () => <App />,
6
+ component: lazyRouteComponent(() => import("./app"), "App"),
6
7
  });
7
8
 
8
9
  const defaultRoute = createRoute({
@@ -230,20 +230,6 @@ const IrisAppExtensionGenerator = async function (tree, options) {
230
230
  return projectJson;
231
231
  });
232
232
  }
233
- if (irisAppExtensionType === "AI_TOOLS_EXTENSION") {
234
- const serversideAiToolsVersion = await getPackageVersion("@trackunit/serverside-ai-tools");
235
- (0, devkit_1.updateJson)(tree, (0, devkit_1.joinPathFragments)(normalizedOptions.projectRoot, "package.json"), packageJson => {
236
- packageJson.dependencies = {
237
- ...packageJson.dependencies,
238
- "@trackunit/serverside-ai-tools": serversideAiToolsVersion,
239
- };
240
- return packageJson;
241
- });
242
- if (normalizedOptions.updatePackageJson) {
243
- // The extension manifest imports the package at build time, from the workspace.
244
- (0, devkit_1.addDependenciesToPackageJson)(tree, { "@trackunit/serverside-ai-tools": serversideAiToolsVersion }, {});
245
- }
246
- }
247
233
  if (normalizedOptions.graphql) {
248
234
  await (0, exports.addServersideGraphql)(tree, {
249
235
  projectName: normalizedOptions.projectName,
@@ -14,7 +14,6 @@ export interface IrisAppExtensionGeneratorSchema {
14
14
  | "ASSET_HOME_EXTENSION"
15
15
  | "ASSET_EVENTS_ACTIONS_EXTENSION"
16
16
  | "LIFECYCLE_EXTENSION"
17
- | "SERVERSIDE_API_EXTENSION"
18
- | "AI_TOOLS_EXTENSION";
17
+ | "SERVERSIDE_API_EXTENSION";
19
18
  graphql?: boolean;
20
19
  }
@@ -56,8 +56,7 @@
56
56
  "CUSTOMER_HOME_EXTENSION",
57
57
  "IRIS_APP_SETTINGS_EXTENSION",
58
58
  "LIFECYCLE_EXTENSION",
59
- "SERVERSIDE_API_EXTENSION",
60
- "AI_TOOLS_EXTENSION"
59
+ "SERVERSIDE_API_EXTENSION"
61
60
  ]
62
61
  }
63
62
  },
@@ -60,3 +60,19 @@ Available extension types:
60
60
  ## Quality Assurance
61
61
 
62
62
  Before completing any task: Always check for and fix all ESLint and TypeScript errors in modified files.
63
+
64
+ ## Claude Code
65
+
66
+ Claude Code (v2.1.277 or later) reads this file directly. A `CLAUDE.md` or `CLAUDE.local.md` stops that; if you need one (older Claude Code, personal notes), make its first line `@AGENTS.md`.
67
+
68
+ SDK-specific skills live in `.agents/skills/`. The generator creates a `.claude/skills` symlink pointing at `../.agents/skills` so Claude Code auto-discovers them. When a skill is referenced in this file, read it from `.agents/skills/[skill-name]/SKILL.md`.
69
+
70
+ Restart Claude Code after changing `.mcp.json` so the MCP servers are reloaded.
71
+
72
+ If skills are not appearing in your available skills list, the symlink may be missing (for example on Windows without Developer Mode, or if a real `.claude/skills` directory existed first). Recreate it with:
73
+
74
+ ```bash
75
+ ln -s ../.agents/skills .claude/skills
76
+ ```
77
+
78
+ If `.claude/skills` already exists as a real directory, move its contents into `.agents/skills/` and delete it before running the command above.
@@ -1,9 +0,0 @@
1
- # Environment variables for local development
2
- # Copy this file to .env and fill in your values
3
- #
4
- # These variables are read by getSecret() from @trackunit/serverside-utils
5
- # The env var name must match the secretKey parameter exactly
6
- #
7
- # Example:
8
- # const apiKey = await getSecret({ context: c, secretKey: "API_KEY" });
9
- # API_KEY=your_api_key_here
@@ -1,16 +0,0 @@
1
- import { AiToolsExtensionManifest } from '@trackunit/iris-app-api';
2
- import { toManifestAiTools } from '@trackunit/serverside-ai-tools';
3
- import { tools } from './src/tools';
4
-
5
- const aiToolsExtensionManifest: AiToolsExtensionManifest = {
6
- id: "<%= projectName %>",
7
- type: "AI_TOOLS_EXTENSION",
8
- runtime: "DENO",
9
- sourceRoot: "dist/<%= projectRoot %>/",
10
- dependencyDefinitionFile: "dist/<%= dependencyDefinitionFile %>",
11
- name: "AI tools <%= projectName %>",
12
- main: "index.js",
13
- aiTools: toManifestAiTools(tools),
14
- };
15
-
16
- export default aiToolsExtensionManifest;
@@ -1,10 +0,0 @@
1
- {
2
- "name": "<%= importPath %>",
3
- "type": "commonjs",
4
- "dependencies": {
5
- "@hono/node-server": "^1.19.17",
6
- "dotenv": "16.3.1",
7
- "hono": "^4.13.5",
8
- "zod": "^3.25.76"
9
- }
10
- }
@@ -1,9 +0,0 @@
1
- import { createAiToolsApp } from "@trackunit/serverside-ai-tools";
2
- import { tools } from "./tools";
3
-
4
- export default createAiToolsApp(tools, {
5
- requiredScope: "account.view",
6
- handlers: {
7
- get_greeting: (_context, { name }) => ({ content: [{ type: "text", text: `Hello, ${name}!` }] }),
8
- },
9
- }).fetch;
@@ -1,11 +0,0 @@
1
- // Auto-generated: mimics the production serverside runtime for local development.
2
- // Do not edit — SDK updates may overwrite changes.
3
- import "dotenv/config";
4
-
5
- import { serve } from "@hono/node-server";
6
-
7
- import handler from "./index";
8
-
9
- const port = Number(process.env.PORT) || 8000;
10
-
11
- serve({ fetch: handler, port });
@@ -1,16 +0,0 @@
1
- import { defineAiTools } from "@trackunit/serverside-ai-tools";
2
- import { z } from "zod";
3
-
4
- // Definitions only: extension-manifest.ts imports this file at build time.
5
- // AI clients see the tools as `<namespace>_<name>`; the namespace must be unique across Trackunit.
6
- export const tools = defineAiTools({
7
- namespace: "<%= projectName %>",
8
- tools: {
9
- get_greeting: {
10
- title: "Get greeting",
11
- description: "Returns a greeting for the given name. Replace this example with your app's tools.",
12
- inputSchema: { name: z.string().min(1).describe("Who to greet.") },
13
- annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
14
- },
15
- },
16
- });