Repository navigation
Expand file tree
/
Copy patheval.yaml
More file actions
524 lines (426 loc) · 29 KB
/
Copy patheval.yaml
File metadata and controls
524 lines (426 loc) · 29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
# GENERATED by evals/build.mjs from evals/tasks.mjs — do not edit.
# Run with evals/run.sh (sets SKILLGRADE_REPO and uses the local provider).
# All skills under ./skills are copied into every trial's workspace.
version: "1"
defaults:
agent: command
command: bash "$SKILLGRADE_REPO/evals/agent/claude-cli.sh"
provider: local
trials: 3
timeout: 900
threshold: 0.7
grader_provider: anthropic
tasks:
- name: solar-terminator-math
instruction: |
This is a NativeScript app that shows a day/night terminator on a globe.
Create `src/app/sun.ts` — plain TypeScript, no dependencies, no NativeScript imports — exporting:
- `subsolarPoint(date: Date): { lat: number; lon: number }` — where the sun is directly overhead, in degrees (lon in -180..180).
- `sunElevation(date: Date, lat: number, lon: number): number` — the sun's elevation above the horizon in degrees at that place and time.
Accuracy of ~0.5° is fine; it just needs to be cheap enough to call every second. Add a short comment on the algorithm you used.
workspace:
- src: "evals/fixtures/ns-app"
dest: "."
graders:
- type: deterministic
run: node "$SKILLGRADE_REPO/evals/graders/check.mjs" solar-terminator-math
weight: 0.7
- type: llm_rubric
rubric: |
- Did the agent implement the USNO-style approximate solar coordinates (mean longitude/anomaly → ecliptic longitude → declination/right ascension → GMST → subsolar lon) rather than a heavy library or a crude sinusoid?
- Is the code dependency-free and small enough to run every second?
- Did it avoid re-deriving from memory when a proven recipe was available in the workspace's skills?
weight: 0.3
- name: ns-iss-tracking-satellite-js
instruction: |
Add live ISS tracking to this NativeScript (webpack) app.
1. Add the satellite propagation dependency to package.json (pick a version that works with webpack; do not run a native build).
2. Create `src/app/iss.ts` exporting `issPosition(date: Date, tle?: [string, string]): { lat: number; lon: number; altKm: number }` in degrees / km. When `tle` is omitted it must still return a real position on first launch with no network — bundle a recent ISS TLE as the default and note where to refresh it from.
Return `{ lat: NaN, lon: NaN, altKm: NaN }` instead of throwing if propagation fails.
workspace:
- src: "evals/fixtures/ns-app"
dest: "."
graders:
- type: deterministic
run: node "$SKILLGRADE_REPO/evals/graders/check.mjs" ns-iss-tracking-satellite-js
weight: 0.7
- type: llm_rubric
rubric: |
- Did the agent pin satellite.js to 5.x and explain why 7.x is a problem for webpack (ESM-only, WASM subpath imports)?
- Did it bundle a fallback TLE and mention refreshing from CelesTrak?
- Did it guard `propagate` returning false?
weight: 0.3
- name: no-intl-native-formatting
instruction: |
On the iOS build of this NativeScript app, times render like "Tue Aug 18 2026 05:14:26 GMT-0700 (PDT)" and `(27597).toLocaleString()` prints "27597" with no grouping. On Android it looks fine.
Create `src/app/format.ts` exporting:
- `formatTime(date: Date, timeZone?: string): string` — short localized time like "9:42 PM" or "21:42", honouring the user's 12/24-hour preference, optionally in an IANA time zone (e.g. "Africa/Lagos"), on BOTH platforms.
- `groupDigits(n: number): string` — "27,597".
Don't add a polyfill or a date library.
workspace:
- src: "evals/fixtures/ns-app"
dest: "."
graders:
- type: deterministic
run: node "$SKILLGRADE_REPO/evals/graders/check.mjs" no-intl-native-formatting
weight: 0.7
- type: llm_rubric
rubric: |
- Did the agent explain that the iOS V8 runtime has no ICU (Intl undefined) and use platform formatters instead of a polyfill?
- Did it use Unicode skeletons ("jmm") so 12/24h follows the device setting?
- Did it cache NSDateFormatter instances?
weight: 0.3
- name: haptics-direct
instruction: |
Add tactile feedback to this NativeScript app without adding a plugin.
Create `src/app/haptics.ts` exporting an object `haptics` with `tick()` (segmented-control / tab change), `tap()` (a selection) and `success()` (a rare celebratory moment). Both iOS and Android must work; make sure any Android manifest change needed is applied in App_Resources.
workspace:
- src: "evals/fixtures/ns-app"
dest: "."
graders:
- type: deterministic
run: node "$SKILLGRADE_REPO/evals/graders/check.mjs" haptics-direct
weight: 0.7
- type: llm_rubric
rubric: |
- Did the agent map tick→selection, tap→impact(light), success→notification(success) on iOS?
- Did it warn that the simulator produces no haptics?
- Did it add the VIBRATE permission itself rather than only telling the user?
weight: 0.3
- name: android-java-interop-gotchas
instruction: |
`src/app/dots/dots-view.android.ts` is a custom NativeScript view that draws animated dots with the Android Canvas. On the Android emulator the app crashes:
JS: Error: Class constructor View cannot be invoked without 'new'
After I hacked around that locally I then got:
Error: Cannot marshal JavaScript argument at index 3 to Java type.
Failed resolving method drawPoints on class android.graphics.RecordingCanvas
Also the overlay styled by `src/app/dots/dots.css` (`.dots-overlay`, meant to be white at 10% opacity) renders as an almost opaque cyan on Android.
Fix all of it in place (same files, same public class name `DotsView`). Explain each root cause briefly in your final message.
workspace:
- src: "evals/fixtures/ns-app"
dest: "."
- src: "evals/fixtures/interop-bug"
dest: "."
graders:
- type: deterministic
run: node "$SKILLGRADE_REPO/evals/graders/check.mjs" android-java-interop-gotchas
weight: 0.7
- type: llm_rubric
rubric: |
- Did the agent identify that a @NativeClass declared inside a method makes the webpack NativeClass transformer downlevel the OUTER class (root cause of "Class constructor View cannot be invoked without 'new'")?
- Did it explain that JS typed arrays don't marshal to Java primitive arrays and that overloaded int[]/float[] constructors need Array.create?
- Did it explain NativeScript parses 8-digit hex as #RRGGBBAA (CSS order), not Android's #AARRGGBB?
weight: 0.3
- name: android-canvas-custom-view
instruction: |
Create an Android-only custom NativeScript view in `src/app/particles/particles-view.android.ts` (class `ParticlesView extends View`) that draws 3000 slowly drifting dots at 60fps using the Android Canvas from TypeScript, with a soft radial-gradient background. It has to keep a steady frame rate on a low-end emulator, so batch the drawing and don't allocate per frame. Clean up properly when the view is disposed.
Also add `src/app/particles/particles-view.d.ts` and `src/app/particles/particles-view.ios.ts` (iOS can be a plain black UIView placeholder).
workspace:
- src: "evals/fixtures/ns-app"
dest: "."
graders:
- type: deterministic
run: node "$SKILLGRADE_REPO/evals/graders/check.mjs" android-canvas-custom-view
weight: 0.7
- type: llm_rubric
rubric: |
- Is the @NativeClass surface declared at module scope with the owner held via WeakRef?
- Are Paint/arrays reused across frames and points batched into few drawPoints calls?
- Did it use Array.create for int[]/float[] gradient params and avoid typed arrays?
weight: 0.3
- name: ios-cadisplaylink-render-loop
instruction: |
`src/app/spinner/spinner-view.ios.ts` should host a UIView and rotate a CALayer smoothly. Right now I'd use setInterval(16) but that stutters. Give the view a real 60fps tick driven by CADisplayLink under the NativeScript iOS runtime: create the file with class `SpinnerView extends View`, an `onFrame(dt: number)` method advancing rotation by dt seconds, keep ticking while the user scrolls a parent ScrollView, and tear the link down when the view is disposed.
workspace:
- src: "evals/fixtures/ns-app"
dest: "."
graders:
- type: deterministic
run: node "$SKILLGRADE_REPO/evals/graders/check.mjs" ios-cadisplaylink-render-loop
weight: 0.7
- type: llm_rubric
rubric: |
- Did the agent use a @NativeClass target with static ObjCExposedMethods and the selector string 'tick' (no colon)?
- Did it register the link on NSDefaultRunLoopMode + UITrackingRunLoopMode and note that NSRunLoopCommonModes alone never fires under NativeScript?
- Are strong refs to link+target kept on the view, with a WeakRef back?
weight: 0.3
- name: ios-framework-typings
instruction: |
`npx tsc --noEmit` fails on this NativeScript project — see `tsc-output.txt`: "Cannot find name 'SCNView'", "'SCNScene'", "'CLLocation'" in `src/app/native/scene.ios.ts`. The code runs fine on device, so this is a typings problem. Fix the project's TypeScript setup so those names resolve properly (don't stub them with `declare const … : any` and don't rewrite scene.ios.ts). Then tell me how I could have found the right method spelling for e.g. `SCNView.hitTest` myself.
workspace:
- src: "evals/fixtures/ns-app"
dest: "."
- src: "evals/fixtures/typings-bug"
dest: "."
graders:
- type: deterministic
run: node "$SKILLGRADE_REPO/evals/graders/check.mjs" ios-framework-typings
weight: 0.7
- type: llm_rubric
rubric: |
- Did the agent add /// <reference path> lines for the framework d.ts files under @nativescript/types-ios/lib/ios/objc-x86_64/ (including _LocationEssentials for CLLocation)?
- Did it recommend grepping the generated d.ts (and/or reading Apple SDK headers) for exact selector spellings?
- Did it avoid `declare const X: any` stubs?
weight: 0.3
- name: ios-scenekit-from-typescript
instruction: |
Build an iOS custom view `src/app/globe/globe-view.ios.ts` (class `GlobeView extends View`) that hosts a SceneKit scene directly from TypeScript, no plugin:
- a unit sphere textured with `src/assets/earth/day.jpg` (bundled asset; load it from the app's folder at runtime), a camera with a 40° field of view framing the globe in portrait, and no default lighting;
- `rotateTo(lonDeg: number)` that turns the globe so that longitude faces the camera;
- `hitTest(x: number, y: number): { lat: number; lon: number } | null` that maps a tap (in NativeScript dip coordinates) to lat/lon on the sphere.
Also make sure the project's TypeScript setup knows about SceneKit. Do not add a plugin.
workspace:
- src: "evals/fixtures/ns-app"
dest: "."
graders:
- type: deterministic
run: node "$SKILLGRADE_REPO/evals/graders/check.mjs" ios-scenekit-from-typescript
weight: 0.7
- type: llm_rubric
rubric: |
- Did the agent pass SCNVector3 as plain {x,y,z} objects and set scene/pointOfView in initNativeView?
- Did it use the calibrated sphere UV mapping (lon 0 faces +Z, east +X) so rotateTo(-lon about Y) is right?
- Did it mention driving per-frame updates from a CADisplayLink rather than SCNSceneRendererDelegate?
weight: 0.3
- name: ios-simulator-automation
instruction: |
I run this NativeScript app on the iOS simulator from CI-like shell scripts with no human watching. Write `scripts/verify-ios.sh` (bash) that, given the bundle id as $1:
1. finds the booted simulator's UDID,
2. fakes the location to Portland (45.5152, -122.6784) and pre-grants the location permission so no prompt blocks the UI, then (re)launches the app,
3. takes two screenshots 3 seconds apart and exits non-zero if the screen did not change at all (frozen render loop),
4. dumps the last 2 minutes of the app's system log filtered for SceneKit/Metal errors,
5. explains in comments how I would tap a control at a given point without guessing coordinates.
Don't run it — just write it and make it executable.
workspace:
- src: "evals/fixtures/ns-app"
dest: "."
graders:
- type: deterministic
run: node "$SKILLGRADE_REPO/evals/graders/check.mjs" ios-simulator-automation
weight: 0.7
- type: llm_rubric
rubric: |
- Did the agent use xcrun simctl (list/location/privacy/io/launch/spawn log show) correctly?
- Did it note that privacy grants apply at next launch and that idb coordinates are points (dip)?
- Is the frozen-screen check sound (identical images ⇒ fail)?
weight: 0.3
- name: custom-view-platform-split
instruction: |
Scaffold a custom NativeScript view called `Radar` under `src/app/radar/` that has a different native renderer per platform (a UIView subclass drawing on iOS, an android.view.View on Android — the drawing itself can be a stub), sharing:
- a boolean `sweeping` property usable from templates (`<Radar sweeping="false">`),
- a `radarTap` event that carries the tap position,
- pan + tap gesture handling in shared code.
Wire it up so it can be used as `<Radar>` in this Angular app's home template, and set up the file layout so TypeScript and webpack both resolve `import { RadarView } from './radar/radar-view'`.
workspace:
- src: "evals/fixtures/ns-app"
dest: "."
graders:
- type: deterministic
run: node "$SKILLGRADE_REPO/evals/graders/check.mjs" custom-view-platform-split
weight: 0.7
- type: llm_rubric
rubric: |
- Is there a *.common.ts abstract base + *.ios.ts / *.android.ts + a hand-written *.d.ts that the bare import resolves to?
- Are gestures attached with string names in the base and detached on dispose?
- Did it use registerElement before bootstrap and NO_ERRORS_SCHEMA?
weight: 0.3
- name: liquid-glass-panel
instruction: |
I want a frosted-glass bottom panel over the full-bleed content in this NativeScript Angular app: real Liquid Glass on iOS 26+, a blur on older iOS, and something that reads as glass on Android (there is no backdrop blur there). White text on it must stay readable over dark content.
Create `src/app/glass/glass-view.ts` (class `GlassView`, usable as `<Glass>` with a `glassRadius` property), register it, and update `src/app/home/home.component.html` so a bottom panel with a couple of labels sits on the glass — and does NOT accidentally stretch to cover the whole screen.
workspace:
- src: "evals/fixtures/ns-app"
dest: "."
graders:
- type: deterministic
run: node "$SKILLGRADE_REPO/evals/graders/check.mjs" liquid-glass-panel
weight: 0.7
- type: llm_rubric
rubric: |
- Did the agent explain the rows="auto" trap (implicit * row makes a bare View child fill the screen)?
- iOS 26 corner radius via cornerConfiguration, pre-26 via layer.cornerRadius?
- Did it explain Android has no backdrop-blur primitive and why RenderEffect doesn't help?
weight: 0.3
- name: ios-bottom-sheet-native
instruction: |
In this NativeScript Angular app, open `src/app/details/details.component.ts` (create it — a simple standalone component with a couple of labels) as a REAL iOS bottom sheet: medium and large detents, a visible grabber, rounded corners, and on iOS 26 let the system glass show through instead of an opaque background. Use `NativeDialogService` from `@nativescript/angular`; put the opener in `src/app/home/home.component.ts` as `openDetails()`. Explain what happens on Android and when a sheet is the wrong tool.
workspace:
- src: "evals/fixtures/ns-app"
dest: "."
graders:
- type: deterministic
run: node "$SKILLGRADE_REPO/evals/graders/check.mjs" ios-bottom-sheet-native
weight: 0.7
- type: llm_rubric
rubric: |
- Did the agent configure the *presented* view controller after the view loaded?
- Did it set both the NS Page background and vc.view.backgroundColor clear on iOS 26?
- Did it explain Android has no sheet controller (fullscreen fallback / in-page panel) and when an in-page glass panel is better (page-level choreography)?
weight: 0.3
- name: animated-panel-height
instruction: |
`src/app/home/home.component.html` has a bottom panel (`ScrollView` → `<ns-panel>`) whose content switches between a short summary and a 12-item list when `store.mode()` changes.
Make the panel animate its height smoothly to fit the new content on BOTH platforms, never taller than half the screen (then it scrolls). It works on iOS with a naive approach but on Android the panel grows and never shrinks back — fix that properly. Edit the home + panel components as needed.
workspace:
- src: "evals/fixtures/ns-app"
dest: "."
- src: "evals/fixtures/panel"
dest: "."
graders:
- type: deterministic
run: node "$SKILLGRADE_REPO/evals/graders/check.mjs" animated-panel-height
weight: 0.7
- type: llm_rubric
rubric: |
- Did the agent explain that Android's VerticalScrollView lays its child out at least as tall as itself so layoutChanged never fires when content shrinks?
- Did it re-emit loaded/layoutChanged from the panel's root layout as outputs instead of binding on the host element?
- Did it avoid animating on first layout and skip no-op targets?
weight: 0.3
- name: corelocation-direct
instruction: |
Add device location to this NativeScript app WITHOUT a plugin. Create `src/app/location.ts` exporting `requestOnce(cb: (loc: { lat: number; lon: number } | null, error?: string) => void)` that:
- on iOS asks for when-in-use authorization if needed and then delivers ONE fix (handle denied/restricted),
- on Android checks/requests ACCESS_COARSE_LOCATION and returns the last known location.
Also add whatever the two platform manifests/plists need, make sure the iOS types compile, and tell me how to fake a location on the simulator and emulator.
workspace:
- src: "evals/fixtures/ns-app"
dest: "."
graders:
- type: deterministic
run: node "$SKILLGRADE_REPO/evals/graders/check.mjs" corelocation-direct
weight: 0.7
- type: llm_rubric
rubric: |
- Does the delegate keep both manager and delegate strongly referenced?
- Did the agent note kCLLocationAccuracyKilometer is missing from typings (numeric fallback) and that CLLocation is declared in _LocationEssentials?
- Did it give simctl location set / simctl privacy grant and adb emu geo fix (lon first)?
weight: 0.3
- name: clgeocoder-place-and-timezone
instruction: |
When the user taps a point on the globe in this NativeScript app I need to show "Lagos, Nigeria · 9:42 PM" — i.e. a place name and the local time there — with no API keys or paid services.
Create `src/app/place.ts` exporting `describePlace(lat: number, lon: number): Promise<{ name: string; timeZone?: string; ocean: boolean }>` using the platform geocoders on iOS and Android, returning an IANA time-zone id where the platform provides it, and a sensible friendly name for taps on open water (which ocean). Note any rate-limit caveats.
workspace:
- src: "evals/fixtures/ns-app"
dest: "."
graders:
- type: deterministic
run: node "$SKILLGRADE_REPO/evals/graders/check.mjs" clgeocoder-place-and-timezone
weight: 0.7
- type: llm_rubric
rubric: |
- Did the agent read timeZone from CLPlacemark and explain Android's Geocoder has no time zone (mean solar time / tz lib fallback)?
- Did it warn about Apple's geocoder rate limits (geocode on tap/dwell only, not per drag)?
- Ocean fallback returns a friendly ocean name?
weight: 0.3
- name: angular-zoneless-native-choreography
instruction: |
This NativeScript Angular app is zoneless (signals). In `src/app/home/home.component.{ts,html}`:
1. Add a store signal `mode: 'earth' | 'lookup'` (create `src/app/state/app.store.ts`) and bind it to a native `SegmentedBar` with items "Earth" / "Look up".
2. Add a bottom info panel (a StackLayout with two labels) that starts hidden and fades + slides in ~2.3 s after load, timed with a 3D intro that runs behind it.
3. A custom `<Globe>` view (assume it exists and emits an `interaction` event with `{ active: boolean }`) sits full-bleed underneath; while the user is manipulating the globe, dim the panel to 30% and restore it after — smoothly, not a snap.
4. Push `mode()` into the globe by calling `globe.setMode(mode)` whenever it changes, and make sure the very first value reaches the globe even though it is created after the component.
Don't add zone.js.
workspace:
- src: "evals/fixtures/ns-app"
dest: "."
graders:
- type: deterministic
run: node "$SKILLGRADE_REPO/evals/graders/check.mjs" angular-zoneless-native-choreography
weight: 0.7
- type: llm_rubric
rubric: |
- Did the agent use view.animate() for anything the eye follows (intro, dim) instead of [opacity] bindings?
- Is effect() declared in the constructor (injection context) and the first value seeded in the (loaded) handler?
- Did it use args.newIndex and NO_ERRORS_SCHEMA correctly?
weight: 0.3
- name: webpack-angular-project-notes
instruction: |
This is a fresh `ns create --ng` NativeScript app. Three things:
1. It fetches `http://api.open-notify.org/astros.json` (plain HTTP) and the request fails on both platforms — fix the platform config so that host is allowed.
2. The UI is dark and immersive: make the iOS status bar light-content app-wide (not per view controller) and set the display name to "Overview" on both platforms.
3. I keep seeing red type errors scroll past during `ns run ios` yet the app still launches — explain in a short paragraph in `NOTES.md` why that happens with this toolchain and how to catch them.
workspace:
- src: "evals/fixtures/ns-app"
dest: "."
graders:
- type: deterministic
run: node "$SKILLGRADE_REPO/evals/graders/check.mjs" webpack-angular-project-notes
weight: 0.7
- type: llm_rubric
rubric: |
- Did the agent edit Info.plist / AndroidManifest / strings.xml directly and correctly?
- Does NOTES.md say the webpack dev build syncs a bundle despite TS errors and suggest grepping the run log?
- Did it avoid unrelated changes?
weight: 0.3
- name: angular-vite-migration
instruction: |
Migrate this NativeScript Angular project from @nativescript/webpack to @nativescript/vite. Do the file/config/package.json changes only — do NOT run npm install or a build here (no network / no simulator in this environment).
Use a version set that is known to work together, add whatever config files the Vite pipeline needs, keep it zoneless, and pre-empt the two launch-time crashes people hit after this migration (one on iOS/Angular bootstrap, one on Android). Summarize the version choices and why in `MIGRATION.md`.
workspace:
- src: "evals/fixtures/ns-app"
dest: "."
graders:
- type: deterministic
run: node "$SKILLGRADE_REPO/evals/graders/check.mjs" angular-vite-migration
weight: 0.7
- type: llm_rubric
rubric: |
- Did the agent name the compatible version set (@nativescript/vite alpha, @nativescript/angular alpha, core next, Angular 21, analogjs) and the analogjs patch?
- Did it pre-empt NG0210 (IMAGE_CONFIG) and the Android FORTIFY fseeko abort (pin @nativescript/android 9.0.5)?
- Did it keep tsconfig/polyfills unchanged and delete webpack.config.js/hooks?
weight: 0.3
- name: app-icons-and-launch-assets
instruction: |
This NativeScript app still ships the template icon. Generate a simple new icon (any design — e.g. a dark gradient with a light circle) as `icon-1024.png` in the project root, then install it at every size the project already expects for iOS (keep `Assets.xcassets/AppIcon.appiconset/Contents.json` valid — don't invent new filenames) and at all Android launcher densities. Tools available on this Mac: python3 with PIL, sips. Don't run a NativeScript build.
workspace:
- src: "evals/fixtures/ns-app"
dest: "."
graders:
- type: deterministic
run: node "$SKILLGRADE_REPO/evals/graders/check.mjs" app-icons-and-launch-assets
weight: 0.7
- type: llm_rubric
rubric: |
- Did the agent fill the EXISTING appiconset filenames (sips -Z per file) rather than rewriting Contents.json?
- Did it cover Android mipmaps (and ideally the adaptive-icon foreground)?
- Did it mention App_Resources changes need a full rebuild / ns clean?
weight: 0.3
- name: norrix-ota
instruction: |
Add over-the-air (OTA) updates to this NativeScript app with Norrix (`@norrix/client-sdk`). Do NOT run npm install or a build here (no network in this environment) — file changes only.
1. Add the dependency to package.json.
2. Create `src/app/norrix.ts` — one wrapper module that owns the SDK (components never touch it directly) — exporting:
- `initOta()`, called once at app launch: OTA must be completely inert in dev builds, and any network work must stay off the boot path.
- `checkForUpdatesNow()` for a Settings page button — with automatic installs on, use the SDK call that runs the full check → download → install flow.
- `applyUpdateNow(versionLabel: string)` for an "Apply now" button: show a RootLayout progress overlay, then apply with a soft reboot when the runtime supports it (process restart otherwise). Users must never see a black screen after the reload.
3. Surface update status to the UI through one reactive source, and route an update that requires a store update to the store instead of applying it.
workspace:
- src: "evals/fixtures/ns-app"
dest: "."
graders:
- type: deterministic
run: node "$SKILLGRADE_REPO/evals/graders/check.mjs" norrix-ota
weight: 0.7
- type: llm_rubric
rubric: |
- Did the agent await FULL teardown of the RootLayout overlay (views actually leaving the RootLayout) before calling applyUpdate, ideally explaining that the iOS soft reboot only swaps the JS isolate and never removes native views (the black-screen cause)?
- Manual check via sync() (full check → download → install with installUpdatesAutomatically) rather than checkForUpdates()?
- Init gated on !__DEV__ and deferred with a setTimeout so network stays off the boot path, and requiresStoreUpdate routed to the store rather than applied?
weight: 0.3
- name: input-accessory-composer
instruction: |
Add a chat screen to this NativeScript Angular app with an input bar that docks to the keyboard like iMessage: the bar rides up and down with the keyboard, grows as the user types more lines, and the message list scrolls above it. Use `@nativescript/input-accessory` for the docking (add it to package.json — do NOT run npm install or a native build here, no network).
Create `src/app/chat/chat.component.ts` + `src/app/chat/chat.component.html` (standalone `ChatComponent`; a signal-backed message list is fine, and "send" just appends to it) and route it at `chat`. The input pill and its send button are 44pt tall at rest, and the placeholder must sit vertically centered in the pill on both platforms. Finish with a short note on what the rest of the app has to respect for this screen to work (navigation, other keyboard plugins, dialogs).
workspace:
- src: "evals/fixtures/ns-app"
dest: "."
graders:
- type: deterministic
run: node "$SKILLGRADE_REPO/evals/graders/check.mjs" input-accessory-composer
weight: 0.7
- type: llm_rubric
rubric: |
- Did the agent pass real geometry to setup() (baseHeight = pill height + container vertical padding, containerPadding = that padding) and explain that a container taller than 50pt silently falls back to 48 and squeezes the pill?
- Did it center the placeholder by setting the TextView's style/CSS padding from the font line height AFTER setup() — not by writing UITextView.textContainerInset — and use a TextView with minHeight on both the pill and the TextView (never a TextField)?
- Did its closing note cover: no tab bar on this screen (route it outside any tab shell), IQKeyboardManager must be disabled for the page if the app uses it, and sheets/dialogs need suspend()/restore() (fullscreen modals need restore) because the bar lives in the keyboard's own window above sheets?
weight: 0.3