Skip to content

Commit 282a8d6

Browse files
bloveclaude
andcommitted
fix(libs): packaging bugs blocking npm consumption of 0.0.1
Smoke-tested @ngaf/*@0.0.1 by tarballing dist/ and installing into a fresh Angular 21 app at ~/tmp/ngaf/smoke-workspace. Three packaging bugs surfaced; all fixed in this commit. 1. @ngaf/a2ui, @ngaf/partial-json, @ngaf/licensing publish-target missing. Their project.json files lacked an explicit nx-release-publish target, so Nx Release defaulted to publishing the project root (raw source) instead of dist/. Added explicit target with packageRoot: "dist/{projectRoot}". 2. @ngaf/a2ui, @ngaf/partial-json built with emitDeclarationOnly: true (inherited from tsconfig.base.json). Their dists contained only .d.ts files, no .js. Added emitDeclarationOnly: false override to libs/a2ui/tsconfig.lib.json and libs/partial-json/tsconfig.lib.json. (libs/licensing already had this override.) 3. @ngaf/chat bundled vitest into the runtime FESM file. runAgentConformance and runAgentWithHistoryConformance import { describe, it, expect } from 'vitest' at module level and were exported from the main public-api. Moved to a secondary entry point @ngaf/chat/testing: - Created libs/chat/testing/ng-package.json + public-api.ts - git mv'd agent-conformance.ts and agent-with-history-conformance .ts (and the conformance spec) into libs/chat/testing/ - Updated their import of Agent/AgentWithHistory from '../agent' to '@ngaf/chat' (cross-entry-point convention) - Removed conformance exports from libs/chat/src/public-api.ts - Added @ngaf/chat/testing path to tsconfig.base.json - Updated internal consumers (libs/ag-ui and libs/langgraph conformance specs) to import from @ngaf/chat/testing. Verified: smoke-app/ag-ui-fake builds (755kB initial), serves at localhost:4300, no minting-service leakage in dist, all @ngaf/* packages credited as MIT in 3rdpartylicenses.txt. smoke-app/langgraph-build builds (606kB initial). This commit fixes the artifacts; next step is to bump to 0.0.2 and republish. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 6d3f728 commit 282a8d6

15 files changed

Lines changed: 415 additions & 25 deletions
Lines changed: 324 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,324 @@
1+
# Fix Packaging Bugs and Publish 0.0.2
2+
3+
> Driven by smoke-test findings (`docs/superpowers/plans/2026-05-01-fresh-install-smoke.md`). The 0.0.1 release is unusable end-to-end; three packages shipped raw source, one bundles vitest into runtime.
4+
5+
**Goal:** Land three packaging fixes, verify locally with `npm pack` + smoke-workspace install, then ship 0.0.2 to npm.
6+
7+
---
8+
9+
## Bug summary
10+
11+
1. **`@ngaf/a2ui`, `@ngaf/partial-json`, `@ngaf/licensing` published as source.** No explicit `nx-release-publish` target in their `project.json`; Nx defaulted to publishing the project root rather than `dist/`.
12+
2. **`@ngaf/chat` bundles vitest into runtime.** `runAgentConformance` and `runAgentWithHistoryConformance` are exported from the main public-api and `import { describe, it, expect } from 'vitest'` at module level. ng-packagr bundles vitest into the FESM file.
13+
3. **`@ngaf/render` import of `@ngaf/licensing` fails to resolve** — consequence of bug #1; fixes itself once `@ngaf/licensing` ships actual JS.
14+
15+
---
16+
17+
## Strategy
18+
19+
- **Fix 1 (mechanical):** Add `nx-release-publish` target to the three TS-only libs.
20+
- **Fix 2 (entry point):** Move conformance helpers to `@ngaf/chat/testing` secondary entry point. `mockAgent` stays on the main entry (no vitest dep) for ergonomic test-fixture use without separate import.
21+
- **Verification before publish:** `npm pack` each lib, install tarballs into `~/tmp/ngaf/smoke-workspace`, confirm build passes.
22+
- **Publish 0.0.2:** standard `nx release version 0.0.2 --specifier=patch && nx release publish` flow.
23+
24+
`@ngaf/langgraph` test helpers (`mockLangGraphAgent`) don't import vitest; leave on main entry. AG-UI's `FakeAgent` and `provideFakeAgUiAgent` are runtime utilities (not tests), no vitest dep; leave on main entry.
25+
26+
---
27+
28+
### Task 1: Add publish config to TS-only libs
29+
30+
**Files:** `libs/a2ui/project.json`, `libs/partial-json/project.json`, `libs/licensing/project.json`
31+
32+
For each, add:
33+
```json
34+
"nx-release-publish": {
35+
"options": {
36+
"packageRoot": "dist/{projectRoot}"
37+
}
38+
}
39+
```
40+
to the `targets` block.
41+
42+
- [ ] **Step 1: Edit each project.json**
43+
44+
```bash
45+
for lib in a2ui partial-json licensing; do
46+
jq '.targets["nx-release-publish"] = { options: { packageRoot: "dist/{projectRoot}" } }' \
47+
libs/$lib/project.json > libs/$lib/project.json.tmp \
48+
&& mv libs/$lib/project.json.tmp libs/$lib/project.json
49+
done
50+
```
51+
52+
- [ ] **Step 2: Verify**
53+
54+
```bash
55+
for lib in a2ui partial-json licensing; do
56+
echo "=== $lib ==="
57+
jq '.targets["nx-release-publish"]' libs/$lib/project.json
58+
done
59+
```
60+
61+
Expected: each shows `{"options": {"packageRoot": "dist/{projectRoot}"}}`.
62+
63+
---
64+
65+
### Task 2: Move conformance helpers to `@ngaf/chat/testing`
66+
67+
**Files:** `libs/chat/src/lib/testing/`, `libs/chat/src/public-api.ts`, new `libs/chat/testing/` secondary entry point.
68+
69+
ng-packagr secondary entry points are colocated subdirectories with their own `ng-package.json`. Convention:
70+
71+
```
72+
libs/chat/
73+
├── ng-package.json # main entry
74+
├── src/
75+
│ ├── public-api.ts
76+
│ └── lib/
77+
│ └── testing/ # source files
78+
│ ├── agent-conformance.ts
79+
│ └── agent-with-history-conformance.ts
80+
└── testing/ # NEW — secondary entry
81+
├── ng-package.json
82+
└── public-api.ts
83+
```
84+
85+
The secondary `testing/public-api.ts` re-exports from the source files. The main `src/public-api.ts` STOPS exporting the conformance helpers.
86+
87+
- [ ] **Step 1: Create `libs/chat/testing/ng-package.json`**
88+
89+
```json
90+
{
91+
"$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
92+
"lib": {
93+
"entryFile": "public-api.ts"
94+
}
95+
}
96+
```
97+
98+
- [ ] **Step 2: Create `libs/chat/testing/public-api.ts`**
99+
100+
```ts
101+
// SPDX-License-Identifier: MIT
102+
export { runAgentConformance } from '../src/lib/testing/agent-conformance';
103+
export { runAgentWithHistoryConformance } from '../src/lib/testing/agent-with-history-conformance';
104+
```
105+
106+
(Keep `mockAgent` on the main entry; it's pure factory code with no vitest dep and is ergonomically useful for component tests.)
107+
108+
- [ ] **Step 3: Update `libs/chat/src/public-api.ts`**
109+
110+
Remove these lines:
111+
```ts
112+
export { runAgentConformance } from './lib/testing/agent-conformance';
113+
export { runAgentWithHistoryConformance } from './lib/testing/agent-with-history-conformance';
114+
```
115+
116+
Keep:
117+
```ts
118+
export { mockAgent } from './lib/testing/mock-agent';
119+
export type { MockAgent, MockAgentOptions } from './lib/testing/mock-agent';
120+
```
121+
122+
- [ ] **Step 4: Update internal references**
123+
124+
`libs/langgraph/src/lib/agent.conformance.spec.ts` imports `runAgentConformance` — currently from `@ngaf/chat`; should now be `@ngaf/chat/testing`.
125+
126+
```bash
127+
rg -l "runAgentConformance|runAgentWithHistoryConformance" libs/ apps/ cockpit/ --glob '!**/dist/**'
128+
```
129+
130+
For each result, change `from '@ngaf/chat'``from '@ngaf/chat/testing'` for these specific imports.
131+
132+
- [ ] **Step 5: Verify chat builds**
133+
134+
```bash
135+
npx nx build chat --skip-nx-cache 2>&1 | tail -3
136+
ls dist/libs/chat/
137+
```
138+
139+
Expected: PASS. `dist/libs/chat/` contains both the main FESM and a `testing/` subdirectory with its own `package.json`/types.
140+
141+
The published artifact will have `exports`:
142+
```json
143+
{
144+
".": { ... main entry ... },
145+
"./testing": { ... testing entry ... }
146+
}
147+
```
148+
149+
(ng-packagr generates this automatically.)
150+
151+
---
152+
153+
### Task 3: Local pack + install verification
154+
155+
Before publishing to npm, validate the fix locally.
156+
157+
- [ ] **Step 1: Build all 7 publishable libs**
158+
159+
```bash
160+
npx nx run-many -t build --projects=chat,langgraph,ag-ui,render,a2ui,partial-json,licensing --skip-nx-cache 2>&1 | tail -3
161+
```
162+
163+
- [ ] **Step 2: Verify each dist has proper artifacts**
164+
165+
```bash
166+
for lib in chat langgraph ag-ui render a2ui partial-json licensing; do
167+
echo "=== $lib ==="
168+
ls dist/libs/$lib/ | head -8
169+
echo "---"
170+
jq '{name, main, module, types, exports: (.exports // "none")}' dist/libs/$lib/package.json 2>&1 | head -10
171+
done
172+
```
173+
174+
Expected for ng-packagr libs (chat/langgraph/ag-ui/render): `fesm2022/`, `types/`, `exports.{".":...}` block.
175+
176+
Expected for tsc libs (a2ui/partial-json/licensing): compiled `.js` + `.d.ts` files, valid `main`/`module`/`types`.
177+
178+
If any lib's `dist/` is missing or has only source: that lib's build target needs investigation.
179+
180+
- [ ] **Step 3: Pack each as a local tarball**
181+
182+
```bash
183+
mkdir -p ~/tmp/ngaf/local-tarballs
184+
rm -f ~/tmp/ngaf/local-tarballs/*.tgz
185+
186+
for lib in chat langgraph ag-ui render a2ui partial-json licensing; do
187+
cd dist/libs/$lib && npm pack --pack-destination ~/tmp/ngaf/local-tarballs && cd -
188+
done
189+
190+
ls ~/tmp/ngaf/local-tarballs/
191+
```
192+
193+
Expected: 7 `.tgz` files.
194+
195+
- [ ] **Step 4: Install local tarballs into smoke workspace**
196+
197+
```bash
198+
cd ~/tmp/ngaf/smoke-workspace
199+
npm install \
200+
~/tmp/ngaf/local-tarballs/ngaf-chat-0.0.1.tgz \
201+
~/tmp/ngaf/local-tarballs/ngaf-ag-ui-0.0.1.tgz \
202+
~/tmp/ngaf/local-tarballs/ngaf-render-0.0.1.tgz \
203+
~/tmp/ngaf/local-tarballs/ngaf-licensing-0.0.1.tgz \
204+
~/tmp/ngaf/local-tarballs/ngaf-a2ui-0.0.1.tgz \
205+
~/tmp/ngaf/local-tarballs/ngaf-partial-json-0.0.1.tgz
206+
```
207+
208+
- [ ] **Step 5: Re-run the AG-UI smoke build**
209+
210+
```bash
211+
cd ~/tmp/ngaf/smoke-workspace
212+
npx ng build ag-ui-fake 2>&1 | tail -10
213+
```
214+
215+
Expected: PASS. If build still fails: capture the new error, address before publish.
216+
217+
If the test imports of `runAgentConformance` need updating to `@ngaf/chat/testing` in the smoke app — they shouldn't, since the AG-UI smoke doesn't use conformance. Only internal lib tests use it.
218+
219+
- [ ] **Step 6: Run dev server (optional but valuable)**
220+
221+
```bash
222+
cd ~/tmp/ngaf/smoke-workspace
223+
npx ng serve ag-ui-fake --port 4300 &
224+
sleep 8
225+
curl -sIo /dev/null -w "%{http_code}\n" http://localhost:4300/
226+
# kill the server
227+
kill %1 2>/dev/null
228+
```
229+
230+
Expected: HTTP 200. Real interactive testing requires browser.
231+
232+
---
233+
234+
### Task 4: Bump and publish 0.0.2
235+
236+
- [ ] **Step 1: Build everything from clean state**
237+
238+
```bash
239+
cd /Users/blove/repos/angular-agent-framework/.claude/worktrees/post-unification-cleanup
240+
rm -rf dist/
241+
npx nx run-many -t build --projects=chat,langgraph,ag-ui,render,a2ui,partial-json,licensing --skip-nx-cache 2>&1 | tail -3
242+
```
243+
244+
- [ ] **Step 2: Version bump**
245+
246+
```bash
247+
npx nx release version --specifier=patch 2>&1 | tail -10
248+
```
249+
250+
Expected: all 7 publishable lib package.json files updated to 0.0.2 (synchronized fixed group).
251+
252+
- [ ] **Step 3: Generate changelog + tag**
253+
254+
```bash
255+
npx nx release changelog 0.0.2 2>&1 | tail -10
256+
```
257+
258+
Expected: `CHANGELOG.md` updated with 0.0.2 entry. New commit `chore(release): publish v0.0.2`. New tag `v0.0.2` (the post-#147 tag pattern; `nx.json` was updated).
259+
260+
- [ ] **Step 4: Source NPM_TOKEN and run publish**
261+
262+
```bash
263+
set -a; source /Users/blove/repos/angular-agent-framework/.env; set +a
264+
npx nx release publish --groups=publishable --access=public --otp=NNNNNN
265+
```
266+
267+
(User provides the OTP at run time; trusted publishing is configured but local-publish still goes through 2FA per npm account settings.)
268+
269+
Expected: 7 packages publish successfully.
270+
271+
- [ ] **Step 5: Push commit + tag**
272+
273+
```bash
274+
git push origin HEAD:main
275+
git push origin v0.0.2
276+
```
277+
278+
Workflow fires on tag push but is idempotent.
279+
280+
- [ ] **Step 6: Verify all 7 at 0.0.2**
281+
282+
```bash
283+
for pkg in chat langgraph ag-ui render a2ui partial-json licensing; do
284+
echo -n "@ngaf/$pkg: "
285+
npm view @ngaf/$pkg version
286+
done
287+
```
288+
289+
Expected: all 7 print `0.0.2`.
290+
291+
---
292+
293+
### Task 5: Re-run the smoke against 0.0.2
294+
295+
After 0.0.2 is on npm:
296+
297+
```bash
298+
cd ~/tmp/ngaf/smoke-workspace
299+
rm -rf node_modules package-lock.json
300+
npm install
301+
# package.json already references @ngaf/* without version pins; will pull 0.0.2
302+
303+
npx ng build ag-ui-fake
304+
npx ng build langgraph-build
305+
```
306+
307+
Expected: both build clean. Then `ng serve ag-ui-fake --port 4300` and confirm in browser.
308+
309+
If anything else fails: capture findings, repeat the fix-publish cycle.
310+
311+
---
312+
313+
## Out of Scope
314+
315+
- Renaming or moving `mockAgent` / `mockLangGraphAgent` / `FakeAgent` / `provideFakeAgUiAgent`. They don't import vitest; their bundle cost is negligible.
316+
- Renaming `lib/testing/` directories.
317+
- Improving Tailwind / theming setup in the smoke app.
318+
- Adding LangGraph live-backend test.
319+
320+
## Risk
321+
322+
- **Multi-package version skew during publish.** If the publish for 0.0.2 fails partway (e.g., OTP timeout), some packages land at 0.0.2 while others stay at 0.0.1. The synchronized fixed group + the `--first-release` style retry pattern (re-run with same OTP for missed packages) mitigates this.
323+
- **Secondary entry-point convention.** Some Angular consumers (older ng-packagr, certain bundlers) have rough edges with secondary entry points. Smoke-test against the AG-UI app catches obvious cases.
324+
- **`@ngaf/langgraph` may have similar issues** that didn't surface yet because the smoke didn't actually try to build the langgraph-build app. After 0.0.2 publishes, the smoke MUST build langgraph-build successfully or we have a third packaging bug.

libs/a2ui/project.json

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,35 @@
33
"$schema": "../../node_modules/nx/schemas/project-schema.json",
44
"sourceRoot": "libs/a2ui/src",
55
"projectType": "library",
6-
"tags": ["scope:shared", "type:lib"],
6+
"tags": [
7+
"scope:shared",
8+
"type:lib"
9+
],
710
"targets": {
811
"build": {
912
"executor": "@nx/js:tsc",
10-
"outputs": ["{workspaceRoot}/dist/libs/a2ui"],
13+
"outputs": [
14+
"{workspaceRoot}/dist/libs/a2ui"
15+
],
1116
"options": {
1217
"outputPath": "dist/libs/a2ui",
1318
"main": "libs/a2ui/src/index.ts",
1419
"tsConfig": "libs/a2ui/tsconfig.lib.json"
1520
}
1621
},
17-
"lint": { "executor": "@nx/eslint:lint" },
22+
"lint": {
23+
"executor": "@nx/eslint:lint"
24+
},
1825
"test": {
1926
"executor": "@nx/vitest:test",
20-
"options": { "configFile": "libs/a2ui/vite.config.mts" }
27+
"options": {
28+
"configFile": "libs/a2ui/vite.config.mts"
29+
}
30+
},
31+
"nx-release-publish": {
32+
"options": {
33+
"packageRoot": "dist/{projectRoot}"
34+
}
2135
}
2236
}
2337
}

libs/a2ui/tsconfig.lib.json

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
{
22
"extends": "./tsconfig.json",
3-
"compilerOptions": { "outDir": "../../dist/out-tsc", "declaration": true },
4-
"include": ["src/**/*.ts"],
5-
"exclude": ["src/**/*.spec.ts"]
3+
"compilerOptions": {
4+
"outDir": "../../dist/out-tsc",
5+
"declaration": true,
6+
"emitDeclarationOnly": false
7+
},
8+
"include": [
9+
"src/**/*.ts"
10+
],
11+
"exclude": [
12+
"src/**/*.spec.ts"
13+
]
614
}

libs/ag-ui/src/lib/to-agent.conformance.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import { Observable } from 'rxjs';
33
import type { AbstractAgent, BaseEvent } from '@ag-ui/client';
44
import type { RunAgentInput } from '@ag-ui/core';
5-
import { runAgentConformance } from '@ngaf/chat';
5+
import { runAgentConformance } from '@ngaf/chat/testing';
66
import { toAgent } from './to-agent';
77

88
/**

0 commit comments

Comments
 (0)