@saschabrunnerch/arcgis-maps-sdk-js-ai-context 0.0.2 → 0.1.0

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 (52) hide show
  1. package/README.md +163 -203
  2. package/bin/cli.js +157 -173
  3. package/contexts/4.34/{claude → skills}/arcgis-3d-advanced/SKILL.md +586 -586
  4. package/contexts/4.34/{claude → skills}/arcgis-advanced-layers/SKILL.md +431 -431
  5. package/contexts/4.34/{claude → skills}/arcgis-analysis-services/SKILL.md +607 -607
  6. package/contexts/4.34/{claude → skills}/arcgis-authentication/SKILL.md +301 -301
  7. package/contexts/4.34/{claude → skills}/arcgis-cim-symbols/SKILL.md +486 -486
  8. package/contexts/4.34/{claude → skills}/arcgis-coordinates-projection/SKILL.md +406 -406
  9. package/contexts/4.34/{claude → skills}/arcgis-core-maps/SKILL.md +739 -739
  10. package/contexts/4.34/{claude → skills}/arcgis-core-utilities/SKILL.md +732 -732
  11. package/contexts/4.34/{claude → skills}/arcgis-custom-rendering/SKILL.md +445 -445
  12. package/contexts/4.34/{claude → skills}/arcgis-editing-advanced/SKILL.md +702 -702
  13. package/contexts/4.34/{claude → skills}/arcgis-feature-effects/SKILL.md +393 -393
  14. package/contexts/4.34/{claude → skills}/arcgis-geometry-operations/SKILL.md +489 -489
  15. package/contexts/4.34/{claude → skills}/arcgis-imagery/SKILL.md +307 -307
  16. package/contexts/4.34/{claude → skills}/arcgis-interaction/SKILL.md +572 -572
  17. package/contexts/4.34/{claude → skills}/arcgis-knowledge-graphs/SKILL.md +582 -582
  18. package/contexts/4.34/{claude → skills}/arcgis-layers/SKILL.md +601 -601
  19. package/contexts/4.34/{claude → skills}/arcgis-map-tools/SKILL.md +668 -668
  20. package/contexts/4.34/{claude → skills}/arcgis-media-layers/SKILL.md +290 -290
  21. package/contexts/4.34/{claude → skills}/arcgis-portal-content/SKILL.md +679 -679
  22. package/contexts/4.34/{claude → skills}/arcgis-scene-effects/SKILL.md +512 -512
  23. package/contexts/4.34/{claude → skills}/arcgis-smart-mapping/SKILL.md +686 -686
  24. package/contexts/4.34/{claude → skills}/arcgis-starter-app-extended/SKILL.md +649 -649
  25. package/contexts/4.34/{claude → skills}/arcgis-tables-forms/SKILL.md +877 -877
  26. package/contexts/4.34/{claude → skills}/arcgis-time-animation/SKILL.md +722 -722
  27. package/contexts/4.34/{claude → skills}/arcgis-utility-networks/SKILL.md +301 -301
  28. package/contexts/4.34/{claude → skills}/arcgis-visualization/SKILL.md +580 -580
  29. package/contexts/4.34/{claude → skills}/arcgis-widgets-ui/SKILL.md +574 -574
  30. package/lib/installer.js +19 -104
  31. package/package.json +45 -45
  32. package/contexts/4.34/copilot/arcgis-3d.instructions.md +0 -267
  33. package/contexts/4.34/copilot/arcgis-analysis.instructions.md +0 -294
  34. package/contexts/4.34/copilot/arcgis-arcade.instructions.md +0 -234
  35. package/contexts/4.34/copilot/arcgis-authentication.instructions.md +0 -187
  36. package/contexts/4.34/copilot/arcgis-cim-symbols.instructions.md +0 -177
  37. package/contexts/4.34/copilot/arcgis-core-maps.instructions.md +0 -246
  38. package/contexts/4.34/copilot/arcgis-core-utilities.instructions.md +0 -247
  39. package/contexts/4.34/copilot/arcgis-editing.instructions.md +0 -262
  40. package/contexts/4.34/copilot/arcgis-geometry.instructions.md +0 -225
  41. package/contexts/4.34/copilot/arcgis-layers.instructions.md +0 -278
  42. package/contexts/4.34/copilot/arcgis-popup-templates.instructions.md +0 -266
  43. package/contexts/4.34/copilot/arcgis-portal-advanced.instructions.md +0 -275
  44. package/contexts/4.34/copilot/arcgis-smart-mapping.instructions.md +0 -184
  45. package/contexts/4.34/copilot/arcgis-starter-app-extended.instructions.md +0 -643
  46. package/contexts/4.34/copilot/arcgis-starter-app.instructions.md +0 -268
  47. package/contexts/4.34/copilot/arcgis-time-animation.instructions.md +0 -112
  48. package/contexts/4.34/copilot/arcgis-visualization.instructions.md +0 -321
  49. package/contexts/4.34/copilot/arcgis-widgets-ui.instructions.md +0 -277
  50. /package/contexts/4.34/{claude → skills}/arcgis-arcade/SKILL.md +0 -0
  51. /package/contexts/4.34/{claude → skills}/arcgis-popup-templates/SKILL.md +0 -0
  52. /package/contexts/4.34/{claude → skills}/arcgis-starter-app/SKILL.md +0 -0
@@ -1,649 +1,649 @@
1
- ---
2
- name: arcgis-starter-app-extended
3
- description: Scaffold a production-ready ArcGIS Maps SDK application with TypeScript, Vite, ESLint, Prettier, git hooks, and GitHub Actions CI/CD.
4
- ---
5
-
6
- # ArcGIS Extended Starter App
7
-
8
- Use this skill to create a production-ready ArcGIS Maps SDK for JavaScript application with comprehensive tooling.
9
-
10
- ## Project Structure
11
-
12
- ```
13
- my-arcgis-app/
14
- ├── .github/
15
- │ └── workflows/
16
- │ ├── test.yml
17
- │ └── deploy.yml
18
- ├── src/
19
- │ ├── main.ts
20
- │ └── style.css
21
- ├── index.html
22
- ├── package.json
23
- ├── tsconfig.json
24
- ├── vite.config.ts
25
- ├── eslint.config.js
26
- ├── .prettierrc
27
- ├── .prettierignore
28
- ├── .editorconfig
29
- ├── .gitattributes
30
- ├── .gitignore
31
- ├── .env.example
32
- └── README.md
33
- ```
34
-
35
- ## package.json
36
-
37
- ```json
38
- {
39
- "name": "my-arcgis-app",
40
- "version": "0.0.1",
41
- "type": "module",
42
- "scripts": {
43
- "dev": "vite",
44
- "build": "tsc && vite build",
45
- "preview": "vite preview",
46
- "lint": "eslint .",
47
- "format:check": "prettier --check .",
48
- "format": "prettier --write .",
49
- "prepare": "simple-git-hooks"
50
- },
51
- "devDependencies": {
52
- "@eslint/js": "^9.39.1",
53
- "eslint": "^9.39.1",
54
- "eslint-config-prettier": "^9.1.0",
55
- "eslint-plugin-import": "^2.29.1",
56
- "eslint-plugin-unicorn": "^55.0.0",
57
- "globals": "^16.5.0",
58
- "prettier": "^3.7.4",
59
- "lint-staged": "^16.2.7",
60
- "simple-git-hooks": "^2.13.1",
61
- "typescript": "~5.9.3",
62
- "typescript-eslint": "^8.49.0",
63
- "vite": "^7.2.7"
64
- },
65
- "dependencies": {
66
- "@arcgis/core": "4.34.8",
67
- "@arcgis/map-components": "^4.34.9",
68
- "@esri/calcite-components": "^3.3.3"
69
- },
70
- "simple-git-hooks": {
71
- "pre-commit": "pnpm exec lint-staged",
72
- "pre-push": "pnpm exec tsc --noEmit"
73
- },
74
- "lint-staged": {
75
- "*.{ts,tsx}": ["eslint --fix", "prettier --write"],
76
- "*.{js,json,css,md,yml,yaml}": ["prettier --write"]
77
- }
78
- }
79
- ```
80
-
81
- ## eslint.config.js
82
-
83
- ```javascript
84
- import eslint from "@eslint/js";
85
- import configPrettier from "eslint-config-prettier";
86
- import importPlugin from "eslint-plugin-import";
87
- import unicornPlugin from "eslint-plugin-unicorn";
88
- import globals from "globals";
89
- import tseslint from "typescript-eslint";
90
-
91
- export default tseslint.config(
92
- eslint.configs.recommended,
93
- ...tseslint.configs.recommended,
94
- // Enable type-aware linting for TypeScript files
95
- {
96
- files: ["**/*.ts", "**/*.tsx"],
97
- languageOptions: {
98
- ecmaVersion: "latest",
99
- sourceType: "module",
100
- parserOptions: {
101
- // Use the project service so ESLint can leverage TS type info
102
- projectService: true,
103
- // Allow type-aware linting for standalone TS config files
104
- allowDefaultProject: ["vite.config.ts"],
105
- },
106
- },
107
- },
108
- // Scope type-checked recommendations strictly to TS files
109
- ...tseslint.configs.recommendedTypeChecked.map((cfg) => ({
110
- ...cfg,
111
- files: ["**/*.ts", "**/*.tsx", "**/*.mts", "**/*.cts"],
112
- })),
113
- {
114
- languageOptions: {
115
- ecmaVersion: "latest",
116
- sourceType: "module",
117
- globals: {
118
- ...globals.browser,
119
- },
120
- },
121
- },
122
- {
123
- ignores: ["dist/**", "node_modules/**"],
124
- },
125
- {
126
- ignores: ["vite.config.ts"],
127
- },
128
- {
129
- plugins: {
130
- import: importPlugin,
131
- unicorn: unicornPlugin,
132
- },
133
- rules: {
134
- // import hygiene
135
- "import/no-duplicates": "error",
136
- "import/no-useless-path-segments": "error",
137
- "import/no-extraneous-dependencies": [
138
- "error",
139
- {
140
- devDependencies: [
141
- "**/eslint.config.*",
142
- "**/vite.config.*",
143
- "**/*.config.*",
144
- "**/scripts/**",
145
- "**/*.test.*",
146
- "**/*.spec.*",
147
- ".github/**",
148
- ],
149
- optionalDependencies: false,
150
- peerDependencies: true,
151
- },
152
- ],
153
- // import ordering (low-noise, helpful for readability)
154
- "import/order": [
155
- "warn",
156
- {
157
- groups: [
158
- "builtin",
159
- "external",
160
- "internal",
161
- "parent",
162
- "sibling",
163
- "index",
164
- "object",
165
- "type",
166
- ],
167
- "newlines-between": "always",
168
- alphabetize: { order: "asc", caseInsensitive: true },
169
- },
170
- ],
171
-
172
- // unused vars/imports (use TS version, disable base rule to avoid false positives)
173
- "no-unused-vars": "off",
174
- "@typescript-eslint/no-unused-vars": [
175
- "warn",
176
- {
177
- argsIgnorePattern: "^_",
178
- varsIgnorePattern: "^_",
179
- caughtErrorsIgnorePattern: "^_",
180
- },
181
- ],
182
-
183
- // code quality
184
- eqeqeq: ["error", "always"],
185
- // Allow console.warn/error for error reporting; flag others
186
- "no-console": ["warn", { allow: ["warn", "error"] }],
187
- "@typescript-eslint/no-explicit-any": "warn",
188
-
189
- // unicorn essentials
190
- "unicorn/prefer-node-protocol": "error",
191
- "unicorn/prefer-string-starts-ends-with": "error",
192
- "unicorn/prefer-array-find": "error",
193
- "unicorn/throw-new-error": "error",
194
-
195
- // typescript consistency (balanced)
196
- "@typescript-eslint/consistent-type-imports": "warn",
197
- "@typescript-eslint/explicit-function-return-type": "off",
198
- "@typescript-eslint/no-require-imports": "error",
199
-
200
- // (Type-aware rules moved to TS-only override below)
201
- },
202
- },
203
- // Node environment for config and build scripts
204
- {
205
- files: ["eslint.config.js", "vite.config.*", "*.config.*", "scripts/**"],
206
- languageOptions: {
207
- globals: {
208
- ...globals.node,
209
- },
210
- },
211
- },
212
- // Declarations: relax strictness for ambient types
213
- {
214
- files: ["**/*.d.ts"],
215
- rules: {
216
- "@typescript-eslint/no-redundant-type-constituents": "off",
217
- "@typescript-eslint/no-unsafe-member-access": "off",
218
- },
219
- },
220
- // TS-only: enable balanced type-aware rules
221
- {
222
- files: ["**/*.ts", "**/*.tsx", "**/*.mts", "**/*.cts"],
223
- rules: {
224
- "@typescript-eslint/no-floating-promises": "error",
225
- "@typescript-eslint/no-misused-promises": [
226
- "error",
227
- { checksVoidReturn: false },
228
- ],
229
- "@typescript-eslint/await-thenable": "warn",
230
-
231
- "@typescript-eslint/no-unsafe-assignment": "off",
232
- "@typescript-eslint/no-unsafe-call": "off",
233
- "@typescript-eslint/no-unsafe-member-access": "off",
234
- "@typescript-eslint/no-unsafe-return": "off",
235
- "@typescript-eslint/no-unsafe-argument": "off",
236
-
237
- "@typescript-eslint/require-await": "off",
238
- "@typescript-eslint/no-unnecessary-type-assertion": "warn",
239
- "@typescript-eslint/no-redundant-type-constituents": "off",
240
- },
241
- },
242
- // Disable ESLint rules that would conflict with Prettier formatting
243
- configPrettier
244
- );
245
- ```
246
-
247
- ## .prettierrc
248
-
249
- ```json
250
- {
251
- "arrowParens": "always",
252
- "bracketSameLine": false,
253
- "bracketSpacing": true,
254
- "endOfLine": "lf",
255
- "jsxSingleQuote": false,
256
- "printWidth": 120,
257
- "quoteProps": "consistent",
258
- "semi": true,
259
- "singleQuote": true,
260
- "tabWidth": 2,
261
- "trailingComma": "all",
262
- "useTabs": false,
263
- "proseWrap": "preserve",
264
- "htmlWhitespaceSensitivity": "css"
265
- }
266
- ```
267
-
268
- ## .prettierignore
269
-
270
- ```
271
- dist/
272
- node_modules/
273
- *.min.js
274
- package-lock.json
275
- pnpm-lock.yaml
276
- ```
277
-
278
- ## .editorconfig
279
-
280
- ```
281
- root = true
282
-
283
- [*]
284
- charset = utf-8
285
- end_of_line = lf
286
- insert_final_newline = true
287
- indent_style = space
288
- indent_size = 2
289
- trim_trailing_whitespace = true
290
-
291
- [*.md]
292
- trim_trailing_whitespace = false
293
- ```
294
-
295
- ## .gitattributes
296
-
297
- ```
298
- * text=auto eol=lf
299
- ```
300
-
301
- ## .gitignore
302
-
303
- ```
304
- node_modules/
305
- dist/
306
- .env
307
- .env.local
308
- .env.*.local
309
- *.log
310
- .DS_Store
311
- *.tsbuildinfo
312
- ```
313
-
314
- ## .env.example
315
-
316
- ```
317
- # ArcGIS API Key
318
- # Get your API key from https://developers.arcgis.com/
319
- VITE_ARCGIS_API_KEY=your_arcgis_api_key_here
320
- ```
321
-
322
- ## .github/workflows/test.yml
323
-
324
- ```yaml
325
- name: Test
326
-
327
- on:
328
- pull_request:
329
- branches:
330
- - main
331
-
332
- permissions:
333
- contents: read
334
- issues: write
335
-
336
- concurrency:
337
- group: ${{ github.workflow }}-${{ github.ref }}
338
- cancel-in-progress: true
339
-
340
- jobs:
341
- test:
342
- runs-on: ubuntu-latest
343
- steps:
344
- - name: Checkout
345
- uses: actions/checkout@v4
346
-
347
- - name: Setup pnpm
348
- uses: pnpm/action-setup@v4
349
- with:
350
- version: 10
351
-
352
- - name: Setup Node.js
353
- uses: actions/setup-node@v4
354
- with:
355
- node-version: "24"
356
- cache: "pnpm"
357
-
358
- - name: Install dependencies
359
- run: pnpm install --frozen-lockfile
360
-
361
- - name: Security audit
362
- run: pnpm audit --audit-level=high
363
-
364
- - name: ESLint
365
- run: pnpm run lint
366
-
367
- - name: Prettier check
368
- run: pnpm run format:check
369
-
370
- - name: Annotate formatting issues
371
- if: failure()
372
- uses: actions/github-script@v7
373
- with:
374
- script: |
375
- const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
376
- const body = [
377
- 'Prettier check failed. Please run `pnpm run format` locally to fix formatting.',
378
- '',
379
- `Workflow run: ${runUrl}`,
380
- ].join('\n');
381
- if (context.payload.pull_request) {
382
- await github.rest.issues.createComment({
383
- owner: context.repo.owner,
384
- repo: context.repo.repo,
385
- issue_number: context.payload.pull_request.number,
386
- body,
387
- });
388
- } else {
389
- core.summary.addHeading('Prettier check failed');
390
- core.summary.addRaw(body);
391
- await core.summary.write();
392
- }
393
-
394
- - name: Type check
395
- run: pnpm exec tsc --noEmit
396
-
397
- - name: Build
398
- run: pnpm run build
399
- env:
400
- NODE_OPTIONS: "--max-old-space-size=4096"
401
- VITE_ARCGIS_API_KEY: ${{ secrets.VITE_ARCGIS_API_KEY }}
402
- ```
403
-
404
- ## .github/workflows/deploy.yml
405
-
406
- ```yaml
407
- name: Build & Deploy to GitHub Pages
408
-
409
- on:
410
- push:
411
- branches:
412
- - main
413
- workflow_dispatch:
414
-
415
- permissions:
416
- contents: read
417
- pages: write
418
- id-token: write
419
-
420
- concurrency:
421
- group: pages
422
- cancel-in-progress: false
423
-
424
- jobs:
425
- build:
426
- runs-on: ubuntu-latest
427
- steps:
428
- - name: Checkout
429
- uses: actions/checkout@v4
430
-
431
- - name: Setup pnpm
432
- uses: pnpm/action-setup@v4
433
- with:
434
- version: 10
435
-
436
- - name: Setup Node.js
437
- uses: actions/setup-node@v4
438
- with:
439
- node-version: "24"
440
- cache: "pnpm"
441
-
442
- - name: Install dependencies
443
- run: pnpm install --frozen-lockfile
444
-
445
- - name: Build
446
- run: pnpm run build
447
- env:
448
- NODE_OPTIONS: "--max-old-space-size=4096"
449
- VITE_ARCGIS_API_KEY: ${{ secrets.VITE_ARCGIS_API_KEY }}
450
-
451
- - name: Setup Pages
452
- uses: actions/configure-pages@v4
453
-
454
- - name: Upload artifact
455
- uses: actions/upload-pages-artifact@v3
456
- with:
457
- path: "./dist"
458
-
459
- deploy:
460
- environment:
461
- name: github-pages
462
- url: ${{ steps.deployment.outputs.page_url }}
463
- runs-on: ubuntu-latest
464
- needs: build
465
- steps:
466
- - name: Deploy to GitHub Pages
467
- id: deployment
468
- uses: actions/deploy-pages@v4
469
- ```
470
-
471
- ## index.html
472
-
473
- ```html
474
- <!DOCTYPE html>
475
- <html lang="en">
476
- <head>
477
- <meta charset="UTF-8" />
478
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
479
- <link rel="icon" type="image/svg+xml" href="/vite.svg" />
480
- <title>ArcGIS Map App</title>
481
- <link rel="stylesheet" href="/src/style.css" />
482
- </head>
483
- <body>
484
- <arcgis-scene item-id="YOUR_WEBSCENE_ID">
485
- <arcgis-zoom slot="top-left"></arcgis-zoom>
486
- <arcgis-navigation-toggle slot="top-left"></arcgis-navigation-toggle>
487
- <arcgis-compass slot="top-left"></arcgis-compass>
488
- </arcgis-scene>
489
- <script type="module" src="/src/main.ts"></script>
490
- </body>
491
- </html>
492
- ```
493
-
494
- ## src/main.ts
495
-
496
- ```typescript
497
- import "@arcgis/map-components/dist/components/arcgis-scene";
498
- import "@arcgis/map-components/dist/components/arcgis-zoom";
499
- import "@arcgis/map-components/dist/components/arcgis-navigation-toggle";
500
- import "@arcgis/map-components/dist/components/arcgis-compass";
501
-
502
- import { setAssetPath as setCalciteAssetPath } from "@esri/calcite-components/dist/components";
503
-
504
- import esriConfig from "@arcgis/core/config";
505
-
506
- // Set Calcite assets path
507
- setCalciteAssetPath("https://js.arcgis.com/calcite-components/3.3.3/assets");
508
-
509
- // Configure ArcGIS API key from environment variable
510
- esriConfig.apiKey = import.meta.env.VITE_ARCGIS_API_KEY as string;
511
-
512
- // Wait for map to be ready
513
- const arcgisScene = document.querySelector("arcgis-scene");
514
- arcgisScene?.addEventListener("arcgisViewReadyChange", (event) => {
515
- const { view } = (event as CustomEvent).detail;
516
- console.warn("Scene view ready:", view);
517
- });
518
- ```
519
-
520
- ## src/style.css
521
-
522
- ```css
523
- @import "@arcgis/core/assets/esri/themes/light/main.css";
524
-
525
- html,
526
- body {
527
- margin: 0;
528
- padding: 0;
529
- width: 100%;
530
- height: 100%;
531
- font-family: "Avenir Next", "Helvetica Neue", Helvetica, Arial, sans-serif;
532
- }
533
-
534
- arcgis-scene,
535
- #viewDiv {
536
- width: 100%;
537
- height: 100%;
538
- }
539
- ```
540
-
541
- ## tsconfig.json
542
-
543
- ```json
544
- {
545
- "compilerOptions": {
546
- "target": "ES2020",
547
- "useDefineForClassFields": true,
548
- "module": "ESNext",
549
- "lib": ["ES2020", "DOM", "DOM.Iterable"],
550
- "skipLibCheck": true,
551
- "moduleResolution": "bundler",
552
- "allowImportingTsExtensions": true,
553
- "isolatedModules": true,
554
- "moduleDetection": "force",
555
- "noEmit": true,
556
- "strict": true,
557
- "noUnusedLocals": true,
558
- "noUnusedParameters": true,
559
- "noFallthroughCasesInSwitch": true,
560
- "noUncheckedSideEffectImports": true
561
- },
562
- "include": ["src"]
563
- }
564
- ```
565
-
566
- ## vite.config.ts
567
-
568
- ```typescript
569
- import { defineConfig } from "vite";
570
-
571
- export default defineConfig({
572
- build: { target: "esnext" },
573
- });
574
- ```
575
-
576
- ## README.md
577
-
578
- ```markdown
579
- # My ArcGIS App
580
-
581
- A web mapping application built with ArcGIS Maps SDK for JavaScript.
582
-
583
- ## Prerequisites
584
-
585
- - Node.js 20+
586
- - pnpm (recommended) or npm
587
-
588
- ## Setup
589
-
590
- 1. Install dependencies:
591
- pnpm install
592
-
593
- 2. Copy environment file and add your API key:
594
- cp .env.example .env
595
-
596
- 3. Start development server:
597
- pnpm dev
598
-
599
- 4. Build for production:
600
- pnpm build
601
-
602
- ## Scripts
603
-
604
- - `pnpm dev` - Start development server
605
- - `pnpm build` - Build for production
606
- - `pnpm preview` - Preview production build
607
- - `pnpm lint` - Run ESLint
608
- - `pnpm format` - Format code with Prettier
609
- - `pnpm format:check` - Check code formatting
610
-
611
- ## Git Hooks
612
-
613
- This project uses simple-git-hooks for automated checks:
614
-
615
- - **pre-commit**: Runs lint-staged (ESLint + Prettier)
616
- - **pre-push**: Runs TypeScript type checking
617
-
618
- ## CI/CD
619
-
620
- GitHub Actions workflows:
621
-
622
- - **test.yml**: Runs on PRs - security audit, lint, format, type check, build
623
- - **deploy.yml**: Deploys to GitHub Pages on push to main
624
-
625
- ## Configuration
626
-
627
- - **API Key**: Set `VITE_ARCGIS_API_KEY` in `.env`
628
- - **Web Scene ID**: Update `YOUR_WEBSCENE_ID` in `index.html`
629
-
630
- ## Technologies
631
-
632
- - ArcGIS Maps SDK for JavaScript
633
- - Calcite Design System
634
- - TypeScript
635
- - Vite
636
- - ESLint + Prettier
637
- - GitHub Actions
638
- ```
639
-
640
- ## Quick Start
641
-
642
- ```bash
643
- pnpm create vite my-arcgis-app --template vanilla-ts
644
- cd my-arcgis-app
645
- pnpm add @arcgis/map-components @arcgis/core @esri/calcite-components
646
- pnpm add -D eslint @eslint/js typescript-eslint eslint-config-prettier eslint-plugin-import eslint-plugin-unicorn globals prettier simple-git-hooks lint-staged
647
- pnpm run prepare
648
- pnpm dev
649
- ```
1
+ ---
2
+ name: arcgis-starter-app-extended
3
+ description: Scaffold a production-ready ArcGIS Maps SDK application with TypeScript, Vite, ESLint, Prettier, git hooks, and GitHub Actions CI/CD.
4
+ ---
5
+
6
+ # ArcGIS Extended Starter App
7
+
8
+ Use this skill to create a production-ready ArcGIS Maps SDK for JavaScript application with comprehensive tooling.
9
+
10
+ ## Project Structure
11
+
12
+ ```
13
+ my-arcgis-app/
14
+ ├── .github/
15
+ │ └── workflows/
16
+ │ ├── test.yml
17
+ │ └── deploy.yml
18
+ ├── src/
19
+ │ ├── main.ts
20
+ │ └── style.css
21
+ ├── index.html
22
+ ├── package.json
23
+ ├── tsconfig.json
24
+ ├── vite.config.ts
25
+ ├── eslint.config.js
26
+ ├── .prettierrc
27
+ ├── .prettierignore
28
+ ├── .editorconfig
29
+ ├── .gitattributes
30
+ ├── .gitignore
31
+ ├── .env.example
32
+ └── README.md
33
+ ```
34
+
35
+ ## package.json
36
+
37
+ ```json
38
+ {
39
+ "name": "my-arcgis-app",
40
+ "version": "0.0.1",
41
+ "type": "module",
42
+ "scripts": {
43
+ "dev": "vite",
44
+ "build": "tsc && vite build",
45
+ "preview": "vite preview",
46
+ "lint": "eslint .",
47
+ "format:check": "prettier --check .",
48
+ "format": "prettier --write .",
49
+ "prepare": "simple-git-hooks"
50
+ },
51
+ "devDependencies": {
52
+ "@eslint/js": "^9.39.1",
53
+ "eslint": "^9.39.1",
54
+ "eslint-config-prettier": "^9.1.0",
55
+ "eslint-plugin-import": "^2.29.1",
56
+ "eslint-plugin-unicorn": "^55.0.0",
57
+ "globals": "^16.5.0",
58
+ "prettier": "^3.7.4",
59
+ "lint-staged": "^16.2.7",
60
+ "simple-git-hooks": "^2.13.1",
61
+ "typescript": "~5.9.3",
62
+ "typescript-eslint": "^8.49.0",
63
+ "vite": "^7.2.7"
64
+ },
65
+ "dependencies": {
66
+ "@arcgis/core": "4.34.8",
67
+ "@arcgis/map-components": "^4.34.9",
68
+ "@esri/calcite-components": "^3.3.3"
69
+ },
70
+ "simple-git-hooks": {
71
+ "pre-commit": "pnpm exec lint-staged",
72
+ "pre-push": "pnpm exec tsc --noEmit"
73
+ },
74
+ "lint-staged": {
75
+ "*.{ts,tsx}": ["eslint --fix", "prettier --write"],
76
+ "*.{js,json,css,md,yml,yaml}": ["prettier --write"]
77
+ }
78
+ }
79
+ ```
80
+
81
+ ## eslint.config.js
82
+
83
+ ```javascript
84
+ import eslint from "@eslint/js";
85
+ import configPrettier from "eslint-config-prettier";
86
+ import importPlugin from "eslint-plugin-import";
87
+ import unicornPlugin from "eslint-plugin-unicorn";
88
+ import globals from "globals";
89
+ import tseslint from "typescript-eslint";
90
+
91
+ export default tseslint.config(
92
+ eslint.configs.recommended,
93
+ ...tseslint.configs.recommended,
94
+ // Enable type-aware linting for TypeScript files
95
+ {
96
+ files: ["**/*.ts", "**/*.tsx"],
97
+ languageOptions: {
98
+ ecmaVersion: "latest",
99
+ sourceType: "module",
100
+ parserOptions: {
101
+ // Use the project service so ESLint can leverage TS type info
102
+ projectService: true,
103
+ // Allow type-aware linting for standalone TS config files
104
+ allowDefaultProject: ["vite.config.ts"],
105
+ },
106
+ },
107
+ },
108
+ // Scope type-checked recommendations strictly to TS files
109
+ ...tseslint.configs.recommendedTypeChecked.map((cfg) => ({
110
+ ...cfg,
111
+ files: ["**/*.ts", "**/*.tsx", "**/*.mts", "**/*.cts"],
112
+ })),
113
+ {
114
+ languageOptions: {
115
+ ecmaVersion: "latest",
116
+ sourceType: "module",
117
+ globals: {
118
+ ...globals.browser,
119
+ },
120
+ },
121
+ },
122
+ {
123
+ ignores: ["dist/**", "node_modules/**"],
124
+ },
125
+ {
126
+ ignores: ["vite.config.ts"],
127
+ },
128
+ {
129
+ plugins: {
130
+ import: importPlugin,
131
+ unicorn: unicornPlugin,
132
+ },
133
+ rules: {
134
+ // import hygiene
135
+ "import/no-duplicates": "error",
136
+ "import/no-useless-path-segments": "error",
137
+ "import/no-extraneous-dependencies": [
138
+ "error",
139
+ {
140
+ devDependencies: [
141
+ "**/eslint.config.*",
142
+ "**/vite.config.*",
143
+ "**/*.config.*",
144
+ "**/scripts/**",
145
+ "**/*.test.*",
146
+ "**/*.spec.*",
147
+ ".github/**",
148
+ ],
149
+ optionalDependencies: false,
150
+ peerDependencies: true,
151
+ },
152
+ ],
153
+ // import ordering (low-noise, helpful for readability)
154
+ "import/order": [
155
+ "warn",
156
+ {
157
+ groups: [
158
+ "builtin",
159
+ "external",
160
+ "internal",
161
+ "parent",
162
+ "sibling",
163
+ "index",
164
+ "object",
165
+ "type",
166
+ ],
167
+ "newlines-between": "always",
168
+ alphabetize: { order: "asc", caseInsensitive: true },
169
+ },
170
+ ],
171
+
172
+ // unused vars/imports (use TS version, disable base rule to avoid false positives)
173
+ "no-unused-vars": "off",
174
+ "@typescript-eslint/no-unused-vars": [
175
+ "warn",
176
+ {
177
+ argsIgnorePattern: "^_",
178
+ varsIgnorePattern: "^_",
179
+ caughtErrorsIgnorePattern: "^_",
180
+ },
181
+ ],
182
+
183
+ // code quality
184
+ eqeqeq: ["error", "always"],
185
+ // Allow console.warn/error for error reporting; flag others
186
+ "no-console": ["warn", { allow: ["warn", "error"] }],
187
+ "@typescript-eslint/no-explicit-any": "warn",
188
+
189
+ // unicorn essentials
190
+ "unicorn/prefer-node-protocol": "error",
191
+ "unicorn/prefer-string-starts-ends-with": "error",
192
+ "unicorn/prefer-array-find": "error",
193
+ "unicorn/throw-new-error": "error",
194
+
195
+ // typescript consistency (balanced)
196
+ "@typescript-eslint/consistent-type-imports": "warn",
197
+ "@typescript-eslint/explicit-function-return-type": "off",
198
+ "@typescript-eslint/no-require-imports": "error",
199
+
200
+ // (Type-aware rules moved to TS-only override below)
201
+ },
202
+ },
203
+ // Node environment for config and build scripts
204
+ {
205
+ files: ["eslint.config.js", "vite.config.*", "*.config.*", "scripts/**"],
206
+ languageOptions: {
207
+ globals: {
208
+ ...globals.node,
209
+ },
210
+ },
211
+ },
212
+ // Declarations: relax strictness for ambient types
213
+ {
214
+ files: ["**/*.d.ts"],
215
+ rules: {
216
+ "@typescript-eslint/no-redundant-type-constituents": "off",
217
+ "@typescript-eslint/no-unsafe-member-access": "off",
218
+ },
219
+ },
220
+ // TS-only: enable balanced type-aware rules
221
+ {
222
+ files: ["**/*.ts", "**/*.tsx", "**/*.mts", "**/*.cts"],
223
+ rules: {
224
+ "@typescript-eslint/no-floating-promises": "error",
225
+ "@typescript-eslint/no-misused-promises": [
226
+ "error",
227
+ { checksVoidReturn: false },
228
+ ],
229
+ "@typescript-eslint/await-thenable": "warn",
230
+
231
+ "@typescript-eslint/no-unsafe-assignment": "off",
232
+ "@typescript-eslint/no-unsafe-call": "off",
233
+ "@typescript-eslint/no-unsafe-member-access": "off",
234
+ "@typescript-eslint/no-unsafe-return": "off",
235
+ "@typescript-eslint/no-unsafe-argument": "off",
236
+
237
+ "@typescript-eslint/require-await": "off",
238
+ "@typescript-eslint/no-unnecessary-type-assertion": "warn",
239
+ "@typescript-eslint/no-redundant-type-constituents": "off",
240
+ },
241
+ },
242
+ // Disable ESLint rules that would conflict with Prettier formatting
243
+ configPrettier
244
+ );
245
+ ```
246
+
247
+ ## .prettierrc
248
+
249
+ ```json
250
+ {
251
+ "arrowParens": "always",
252
+ "bracketSameLine": false,
253
+ "bracketSpacing": true,
254
+ "endOfLine": "lf",
255
+ "jsxSingleQuote": false,
256
+ "printWidth": 120,
257
+ "quoteProps": "consistent",
258
+ "semi": true,
259
+ "singleQuote": true,
260
+ "tabWidth": 2,
261
+ "trailingComma": "all",
262
+ "useTabs": false,
263
+ "proseWrap": "preserve",
264
+ "htmlWhitespaceSensitivity": "css"
265
+ }
266
+ ```
267
+
268
+ ## .prettierignore
269
+
270
+ ```
271
+ dist/
272
+ node_modules/
273
+ *.min.js
274
+ package-lock.json
275
+ pnpm-lock.yaml
276
+ ```
277
+
278
+ ## .editorconfig
279
+
280
+ ```
281
+ root = true
282
+
283
+ [*]
284
+ charset = utf-8
285
+ end_of_line = lf
286
+ insert_final_newline = true
287
+ indent_style = space
288
+ indent_size = 2
289
+ trim_trailing_whitespace = true
290
+
291
+ [*.md]
292
+ trim_trailing_whitespace = false
293
+ ```
294
+
295
+ ## .gitattributes
296
+
297
+ ```
298
+ * text=auto eol=lf
299
+ ```
300
+
301
+ ## .gitignore
302
+
303
+ ```
304
+ node_modules/
305
+ dist/
306
+ .env
307
+ .env.local
308
+ .env.*.local
309
+ *.log
310
+ .DS_Store
311
+ *.tsbuildinfo
312
+ ```
313
+
314
+ ## .env.example
315
+
316
+ ```
317
+ # ArcGIS API Key
318
+ # Get your API key from https://developers.arcgis.com/
319
+ VITE_ARCGIS_API_KEY=your_arcgis_api_key_here
320
+ ```
321
+
322
+ ## .github/workflows/test.yml
323
+
324
+ ```yaml
325
+ name: Test
326
+
327
+ on:
328
+ pull_request:
329
+ branches:
330
+ - main
331
+
332
+ permissions:
333
+ contents: read
334
+ issues: write
335
+
336
+ concurrency:
337
+ group: ${{ github.workflow }}-${{ github.ref }}
338
+ cancel-in-progress: true
339
+
340
+ jobs:
341
+ test:
342
+ runs-on: ubuntu-latest
343
+ steps:
344
+ - name: Checkout
345
+ uses: actions/checkout@v4
346
+
347
+ - name: Setup pnpm
348
+ uses: pnpm/action-setup@v4
349
+ with:
350
+ version: 10
351
+
352
+ - name: Setup Node.js
353
+ uses: actions/setup-node@v4
354
+ with:
355
+ node-version: "24"
356
+ cache: "pnpm"
357
+
358
+ - name: Install dependencies
359
+ run: pnpm install --frozen-lockfile
360
+
361
+ - name: Security audit
362
+ run: pnpm audit --audit-level=high
363
+
364
+ - name: ESLint
365
+ run: pnpm run lint
366
+
367
+ - name: Prettier check
368
+ run: pnpm run format:check
369
+
370
+ - name: Annotate formatting issues
371
+ if: failure()
372
+ uses: actions/github-script@v7
373
+ with:
374
+ script: |
375
+ const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
376
+ const body = [
377
+ 'Prettier check failed. Please run `pnpm run format` locally to fix formatting.',
378
+ '',
379
+ `Workflow run: ${runUrl}`,
380
+ ].join('\n');
381
+ if (context.payload.pull_request) {
382
+ await github.rest.issues.createComment({
383
+ owner: context.repo.owner,
384
+ repo: context.repo.repo,
385
+ issue_number: context.payload.pull_request.number,
386
+ body,
387
+ });
388
+ } else {
389
+ core.summary.addHeading('Prettier check failed');
390
+ core.summary.addRaw(body);
391
+ await core.summary.write();
392
+ }
393
+
394
+ - name: Type check
395
+ run: pnpm exec tsc --noEmit
396
+
397
+ - name: Build
398
+ run: pnpm run build
399
+ env:
400
+ NODE_OPTIONS: "--max-old-space-size=4096"
401
+ VITE_ARCGIS_API_KEY: ${{ secrets.VITE_ARCGIS_API_KEY }}
402
+ ```
403
+
404
+ ## .github/workflows/deploy.yml
405
+
406
+ ```yaml
407
+ name: Build & Deploy to GitHub Pages
408
+
409
+ on:
410
+ push:
411
+ branches:
412
+ - main
413
+ workflow_dispatch:
414
+
415
+ permissions:
416
+ contents: read
417
+ pages: write
418
+ id-token: write
419
+
420
+ concurrency:
421
+ group: pages
422
+ cancel-in-progress: false
423
+
424
+ jobs:
425
+ build:
426
+ runs-on: ubuntu-latest
427
+ steps:
428
+ - name: Checkout
429
+ uses: actions/checkout@v4
430
+
431
+ - name: Setup pnpm
432
+ uses: pnpm/action-setup@v4
433
+ with:
434
+ version: 10
435
+
436
+ - name: Setup Node.js
437
+ uses: actions/setup-node@v4
438
+ with:
439
+ node-version: "24"
440
+ cache: "pnpm"
441
+
442
+ - name: Install dependencies
443
+ run: pnpm install --frozen-lockfile
444
+
445
+ - name: Build
446
+ run: pnpm run build
447
+ env:
448
+ NODE_OPTIONS: "--max-old-space-size=4096"
449
+ VITE_ARCGIS_API_KEY: ${{ secrets.VITE_ARCGIS_API_KEY }}
450
+
451
+ - name: Setup Pages
452
+ uses: actions/configure-pages@v4
453
+
454
+ - name: Upload artifact
455
+ uses: actions/upload-pages-artifact@v3
456
+ with:
457
+ path: "./dist"
458
+
459
+ deploy:
460
+ environment:
461
+ name: github-pages
462
+ url: ${{ steps.deployment.outputs.page_url }}
463
+ runs-on: ubuntu-latest
464
+ needs: build
465
+ steps:
466
+ - name: Deploy to GitHub Pages
467
+ id: deployment
468
+ uses: actions/deploy-pages@v4
469
+ ```
470
+
471
+ ## index.html
472
+
473
+ ```html
474
+ <!DOCTYPE html>
475
+ <html lang="en">
476
+ <head>
477
+ <meta charset="UTF-8" />
478
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
479
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
480
+ <title>ArcGIS Map App</title>
481
+ <link rel="stylesheet" href="/src/style.css" />
482
+ </head>
483
+ <body>
484
+ <arcgis-scene item-id="YOUR_WEBSCENE_ID">
485
+ <arcgis-zoom slot="top-left"></arcgis-zoom>
486
+ <arcgis-navigation-toggle slot="top-left"></arcgis-navigation-toggle>
487
+ <arcgis-compass slot="top-left"></arcgis-compass>
488
+ </arcgis-scene>
489
+ <script type="module" src="/src/main.ts"></script>
490
+ </body>
491
+ </html>
492
+ ```
493
+
494
+ ## src/main.ts
495
+
496
+ ```typescript
497
+ import "@arcgis/map-components/dist/components/arcgis-scene";
498
+ import "@arcgis/map-components/dist/components/arcgis-zoom";
499
+ import "@arcgis/map-components/dist/components/arcgis-navigation-toggle";
500
+ import "@arcgis/map-components/dist/components/arcgis-compass";
501
+
502
+ import { setAssetPath as setCalciteAssetPath } from "@esri/calcite-components/dist/components";
503
+
504
+ import esriConfig from "@arcgis/core/config";
505
+
506
+ // Set Calcite assets path
507
+ setCalciteAssetPath("https://js.arcgis.com/calcite-components/3.3.3/assets");
508
+
509
+ // Configure ArcGIS API key from environment variable
510
+ esriConfig.apiKey = import.meta.env.VITE_ARCGIS_API_KEY as string;
511
+
512
+ // Wait for map to be ready
513
+ const arcgisScene = document.querySelector("arcgis-scene");
514
+ arcgisScene?.addEventListener("arcgisViewReadyChange", (event) => {
515
+ const { view } = (event as CustomEvent).detail;
516
+ console.warn("Scene view ready:", view);
517
+ });
518
+ ```
519
+
520
+ ## src/style.css
521
+
522
+ ```css
523
+ @import "@arcgis/core/assets/esri/themes/light/main.css";
524
+
525
+ html,
526
+ body {
527
+ margin: 0;
528
+ padding: 0;
529
+ width: 100%;
530
+ height: 100%;
531
+ font-family: "Avenir Next", "Helvetica Neue", Helvetica, Arial, sans-serif;
532
+ }
533
+
534
+ arcgis-scene,
535
+ #viewDiv {
536
+ width: 100%;
537
+ height: 100%;
538
+ }
539
+ ```
540
+
541
+ ## tsconfig.json
542
+
543
+ ```json
544
+ {
545
+ "compilerOptions": {
546
+ "target": "ES2020",
547
+ "useDefineForClassFields": true,
548
+ "module": "ESNext",
549
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
550
+ "skipLibCheck": true,
551
+ "moduleResolution": "bundler",
552
+ "allowImportingTsExtensions": true,
553
+ "isolatedModules": true,
554
+ "moduleDetection": "force",
555
+ "noEmit": true,
556
+ "strict": true,
557
+ "noUnusedLocals": true,
558
+ "noUnusedParameters": true,
559
+ "noFallthroughCasesInSwitch": true,
560
+ "noUncheckedSideEffectImports": true
561
+ },
562
+ "include": ["src"]
563
+ }
564
+ ```
565
+
566
+ ## vite.config.ts
567
+
568
+ ```typescript
569
+ import { defineConfig } from "vite";
570
+
571
+ export default defineConfig({
572
+ build: { target: "esnext" },
573
+ });
574
+ ```
575
+
576
+ ## README.md
577
+
578
+ ```markdown
579
+ # My ArcGIS App
580
+
581
+ A web mapping application built with ArcGIS Maps SDK for JavaScript.
582
+
583
+ ## Prerequisites
584
+
585
+ - Node.js 20+
586
+ - pnpm (recommended) or npm
587
+
588
+ ## Setup
589
+
590
+ 1. Install dependencies:
591
+ pnpm install
592
+
593
+ 2. Copy environment file and add your API key:
594
+ cp .env.example .env
595
+
596
+ 3. Start development server:
597
+ pnpm dev
598
+
599
+ 4. Build for production:
600
+ pnpm build
601
+
602
+ ## Scripts
603
+
604
+ - `pnpm dev` - Start development server
605
+ - `pnpm build` - Build for production
606
+ - `pnpm preview` - Preview production build
607
+ - `pnpm lint` - Run ESLint
608
+ - `pnpm format` - Format code with Prettier
609
+ - `pnpm format:check` - Check code formatting
610
+
611
+ ## Git Hooks
612
+
613
+ This project uses simple-git-hooks for automated checks:
614
+
615
+ - **pre-commit**: Runs lint-staged (ESLint + Prettier)
616
+ - **pre-push**: Runs TypeScript type checking
617
+
618
+ ## CI/CD
619
+
620
+ GitHub Actions workflows:
621
+
622
+ - **test.yml**: Runs on PRs - security audit, lint, format, type check, build
623
+ - **deploy.yml**: Deploys to GitHub Pages on push to main
624
+
625
+ ## Configuration
626
+
627
+ - **API Key**: Set `VITE_ARCGIS_API_KEY` in `.env`
628
+ - **Web Scene ID**: Update `YOUR_WEBSCENE_ID` in `index.html`
629
+
630
+ ## Technologies
631
+
632
+ - ArcGIS Maps SDK for JavaScript
633
+ - Calcite Design System
634
+ - TypeScript
635
+ - Vite
636
+ - ESLint + Prettier
637
+ - GitHub Actions
638
+ ```
639
+
640
+ ## Quick Start
641
+
642
+ ```bash
643
+ pnpm create vite my-arcgis-app --template vanilla-ts
644
+ cd my-arcgis-app
645
+ pnpm add @arcgis/map-components @arcgis/core @esri/calcite-components
646
+ pnpm add -D eslint @eslint/js typescript-eslint eslint-config-prettier eslint-plugin-import eslint-plugin-unicorn globals prettier simple-git-hooks lint-staged
647
+ pnpm run prepare
648
+ pnpm dev
649
+ ```