@networkpro/web 1.26.2 β†’ 1.26.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.env.codex ADDED
@@ -0,0 +1,10 @@
1
+ # Build + code-path semantics
2
+ ENV_MODE=production
3
+ PUBLIC_ENV_MODE=production
4
+
5
+ # Explicit signal this is not real prod
6
+ CODEX=true
7
+ PUBLIC_CODEX=true
8
+
9
+ # Analytics / telemetry stub
10
+ PUBLIC_POSTHOG_KEY=DUMMY
@@ -45,7 +45,7 @@ jobs:
45
45
  - name: Upgrade npm
46
46
  run: |
47
47
  corepack enable
48
- npm install -g npm@11.7.0
48
+ npm install -g npm@11.8.0
49
49
 
50
50
  - name: Install Node.js dependencies
51
51
  run: npm ci
@@ -130,7 +130,7 @@ jobs:
130
130
  - name: Upgrade npm
131
131
  run: |
132
132
  corepack enable
133
- npm install -g npm@11.7.0
133
+ npm install -g npm@11.8.0
134
134
 
135
135
  - name: Install Node.js dependencies
136
136
  run: npm ci
@@ -186,7 +186,7 @@ jobs:
186
186
  - name: Upgrade npm
187
187
  run: |
188
188
  corepack enable
189
- npm install -g npm@11.7.0
189
+ npm install -g npm@11.8.0
190
190
 
191
191
  - name: Install Node.js dependencies
192
192
  run: npm ci
@@ -23,7 +23,7 @@ jobs:
23
23
 
24
24
  steps:
25
25
  - name: Checkout repo
26
- uses: actions/checkout@v5
26
+ uses: actions/checkout@v6
27
27
 
28
28
  - name: Check security.txt expiration
29
29
  run: |
@@ -49,7 +49,7 @@ jobs:
49
49
  - name: Upgrade npm
50
50
  run: |
51
51
  corepack enable
52
- npm install -g npm@11.7.0
52
+ npm install -g npm@11.8.0
53
53
 
54
54
  - name: Clean previous Lighthouse reports
55
55
  run: |
@@ -152,7 +152,7 @@ jobs:
152
152
  run: ls -al .lighthouseci
153
153
 
154
154
  - name: Upload full .lighthouseci output
155
- uses: actions/upload-artifact@v4
155
+ uses: actions/upload-artifact@v6
156
156
  with:
157
157
  name: lighthouse-reports
158
158
  path: .lighthouseci/
@@ -41,7 +41,7 @@ jobs:
41
41
  - name: Upgrade npm
42
42
  run: |
43
43
  corepack enable
44
- npm install -g npm@11.7.0
44
+ npm install -g npm@11.8.0
45
45
 
46
46
  - name: Install Node.js dependencies
47
47
  run: npm ci
@@ -57,7 +57,7 @@ jobs:
57
57
 
58
58
  - name: Upload Playwright report
59
59
  if: always()
60
- uses: actions/upload-artifact@v4
60
+ uses: actions/upload-artifact@v6
61
61
  with:
62
62
  name: playwright-report
63
63
  path: playwright-report/
@@ -40,15 +40,15 @@ jobs:
40
40
  cache: npm
41
41
  cache-dependency-path: package-lock.json
42
42
 
43
- #- name: Show Node.js and npm versions
44
- # run: |
45
- # echo "Node.js version: $(node -v)"
46
- # echo "npm version: $(npm -v)"
43
+ - name: Show Node.js and npm versions
44
+ run: |
45
+ echo "Node.js version: $(node -v)"
46
+ echo "npm version: $(npm -v)"
47
47
 
48
48
  - name: Upgrade npm
49
49
  run: |
50
50
  corepack enable
51
- npm install -g npm@11.7.0
51
+ npm install -g npm@11.8.0
52
52
 
53
53
  - name: Install Node.js dependencies
54
54
  run: npm ci
@@ -126,15 +126,15 @@ jobs:
126
126
  cache: npm
127
127
  cache-dependency-path: package-lock.json
128
128
 
129
- #- name: Show Node.js and npm versions
130
- # run: |
131
- # echo "Node.js version: $(node -v)"
132
- # echo "npm version: $(npm -v)"
129
+ - name: Show Node.js and npm versions
130
+ run: |
131
+ echo "Node.js version: $(node -v)"
132
+ echo "npm version: $(npm -v)"
133
133
 
134
134
  - name: Upgrade npm
135
135
  run: |
136
136
  corepack enable
137
- npm install -g npm@11.7.0
137
+ npm install -g npm@11.8.0
138
138
 
139
139
  - name: Install Node.js dependencies
140
140
  run: npm ci
@@ -187,15 +187,15 @@ jobs:
187
187
  cache: npm
188
188
  cache-dependency-path: package-lock.json
189
189
 
190
- #- name: Show Node.js and npm versions
191
- # run: |
192
- # echo "Node.js version: $(node -v)"
193
- # echo "npm version: $(npm -v)"
190
+ - name: Show Node.js and npm versions
191
+ run: |
192
+ echo "Node.js version: $(node -v)"
193
+ echo "npm version: $(npm -v)"
194
194
 
195
195
  - name: Upgrade npm
196
196
  run: |
197
197
  corepack enable
198
- npm install -g npm@11.7.0
198
+ npm install -g npm@11.8.0
199
199
 
200
200
  - name: Install Node.js dependencies
201
201
  run: npm ci
@@ -96,7 +96,7 @@ jobs:
96
96
  # ---------------------------------------------------------------------
97
97
  - name: Create issue for detected secrets
98
98
  if: failure() && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository)
99
- uses: actions/github-script@v7
99
+ uses: actions/github-script@v8
100
100
  with:
101
101
  github-token: ${{ secrets.GITHUB_TOKEN }}
102
102
  script: |
@@ -53,7 +53,7 @@ jobs:
53
53
  - name: Upgrade npm
54
54
  run: |
55
55
  corepack enable
56
- npm install -g npm@11.7.0
56
+ npm install -g npm@11.8.0
57
57
 
58
58
  - name: Install Node.js dependencies
59
59
  run: npm ci
@@ -134,7 +134,7 @@ jobs:
134
134
  - name: Upgrade npm
135
135
  run: |
136
136
  corepack enable
137
- npm install -g npm@11.7.0
137
+ npm install -g npm@11.8.0
138
138
 
139
139
  - name: Install Node.js dependencies
140
140
  run: npm ci
@@ -190,7 +190,7 @@ jobs:
190
190
  - name: Upgrade npm
191
191
  run: |
192
192
  corepack enable
193
- npm install -g npm@11.7.0
193
+ npm install -g npm@11.8.0
194
194
 
195
195
  - name: Install Node.js dependencies
196
196
  run: npm ci
@@ -41,5 +41,6 @@
41
41
  "css.customData": [
42
42
  ".vscode/customData.json" // Path to your custom data file
43
43
  ],
44
- "markdown.validate.enabled": false
44
+ "markdown.validate.enabled": false,
45
+ "chatgpt.openOnStartup": false
45
46
  }
package/AGENTS.md ADDED
@@ -0,0 +1,182 @@
1
+ # AGENTS.md
2
+
3
+ This file defines **operational guidance for automated agents** (e.g., Codex,
4
+ Claude Code, CI bots) working in this repository. It is intentionally
5
+ tool-neutral.
6
+
7
+ For deeper project context, architecture notes, and AI-specific guidance, see
8
+ `CLAUDE.md`.
9
+
10
+ ---
11
+
12
+ ## Purpose
13
+
14
+ Agents are welcome here to accelerate development, testing, and maintenance β€”
15
+ **without compromising security, privacy, or deployment correctness**.
16
+
17
+ This repo has intentionally strict security controls (CSP, audit mode behavior,
18
+ analytics gating) and a multi-environment deployment model. Agents must treat
19
+ these as **invariants** unless a human explicitly approves changes.
20
+
21
+ ---
22
+
23
+ ## Agent workflow (persona)
24
+
25
+ - Prefer minimal diffs; avoid sweeping refactors unless requested.
26
+ - Be explicit about tradeoffs and risks; don’t guess about CI/deploy behavior.
27
+ - Preserve behavior by default; if a change alters behavior, call it out explicitly.
28
+ - Preserve invariants: env detection, CSP, audit-mode guarantees, analytics gating.
29
+ - If unsure, ask a single targeted question or leave a TODO rather than inventing.
30
+ - Optimize for reproducibility: commands that work locally and in CI.
31
+
32
+ ---
33
+
34
+ ## Quick Commands
35
+
36
+ Use these commands as the β€œhappy path” for local and CI-like validation:
37
+
38
+ ### Development
39
+
40
+ - `npm run dev` β€” start dev server
41
+ - `npm run dev:audit` β€” dev server in audit mode (hardened CSP, no analytics)
42
+ - `npm run preview` β€” preview production build locally
43
+
44
+ ### Build
45
+
46
+ - `npm run build` β€” production build
47
+ - `npm run build:audit` β€” audit build (hardened CSP)
48
+
49
+ ### Tests
50
+
51
+ - `npm run test:all` β€” unit tests (client + server)
52
+ - `npm run test:e2e` β€” Playwright E2E tests (with 1 retry)
53
+ - `npm run lhci:run` β€” Lighthouse CI audits
54
+
55
+ ### Lint / Format
56
+
57
+ - `npm run lint:all`
58
+ - `npm run lint:fix`
59
+ - `npm run format:fix`
60
+
61
+ ### Full Verification
62
+
63
+ - `npm run checkout` (alias: `npm run verify`)
64
+
65
+ ---
66
+
67
+ ## Guardrails (Strict, but Practical)
68
+
69
+ ### Environment and security invariants
70
+
71
+ Agents MUST NOT change the following without explicit human approval:
72
+
73
+ - **Environment detection logic** (notably `src/lib/utils/env.js`) or introduce
74
+ new environment modes.
75
+ - **Content Security Policy** generation/behavior (`src/hooks.server.js`) in a
76
+ way that weakens enforcement.
77
+ - **Audit-mode guarantees**: audit must remain hardened (no analytics, no
78
+ external reporting, strict CSP).
79
+ - **Analytics gating**: tracking must remain consent-based and
80
+ environment-aware.
81
+ - **Service worker exclusions**: analytics domains must not be cached; SW bypass
82
+ behavior must remain intact.
83
+
84
+ If a task requires touching any of the above, stop and ask for confirmation.
85
+
86
+ ### Deployment and CI/CD accuracy
87
+
88
+ Agents MUST NOT invent deployment behavior. The current model is:
89
+
90
+ - **Production**: Vercel builds/deploys on merges to `master` (Vercel-managed).
91
+ - **Audit**: Netlify deploy driven by a branch-scoped GitHub Actions workflow
92
+ (`audit-netlify` branch only).
93
+
94
+ If a change would affect build/deploy behavior, document assumptions and ask for
95
+ confirmation.
96
+
97
+ If referencing a workflow/config, point to the exact file path and branch it lives on.
98
+
99
+ ### Secrets and sensitive data
100
+
101
+ - Do **not** commit secrets, tokens, keys, or credentials.
102
+ - `.env*` files must remain purpose-separated. Only non-sensitive, commit-safe
103
+ env files belong in git.
104
+ - If secrets are required for a task, request them via the tool’s secret
105
+ mechanism and use placeholders in committed files.
106
+
107
+ ---
108
+
109
+ ## Allowed Agent Work
110
+
111
+ Agents MAY do the following without additional approval (assuming guardrails are
112
+ respected):
113
+
114
+ - Explain code and architecture; summarize behavior and risks.
115
+ - Implement **incremental** features or routes that follow existing patterns.
116
+ - Fix bugs and reduce flakiness in tests using minimal, targeted changes.
117
+ - For SPA E2E tests, prefer URL polling + page-ready assertions over navigation lifecycle waits.
118
+ - Add/extend unit tests or E2E tests consistent with current test architecture.
119
+ - Refactor for clarity **without changing behavior** (especially in security/env
120
+ paths).
121
+ - Improve documentation, comments, and JSDoc.
122
+ - Propose dependency updates, with a short rationale and any expected impact.
123
+
124
+ ---
125
+
126
+ ## Sensitive Areas (Ask Before Major Changes)
127
+
128
+ These areas are high-impact. Changes are allowed, but require extra care and
129
+ usually a quick human check:
130
+
131
+ - `src/lib/utils/env.js` (environment resolution)
132
+ - `src/hooks.server.js` (CSP / security headers)
133
+ - `src/service-worker.js` and SW registration logic
134
+ - `src/lib/stores/posthog.js` and analytics init/gating
135
+ - Auth, redirects, proxy/relay routes under `src/routes/relay-*`
136
+ - Build tooling (`vite.config.js`, `svelte.config.js`, CI workflows, deploy
137
+ scripts)
138
+
139
+ When editing these, prefer:
140
+
141
+ - minimal diffs
142
+ - explicit control flow
143
+ - comments describing intent and risk
144
+
145
+ ---
146
+
147
+ ## What β€œDone” Means for Agent Work
148
+
149
+ Before claiming a task is complete, agents should:
150
+
151
+ 1. Ensure changes are minimal and aligned with existing patterns.
152
+ 2. Run (or at least recommend running) appropriate checks:
153
+ - `npm run lint:all`
154
+ - `npm run test:all`
155
+ - `npm run test:e2e` (if UI/routes are affected)
156
+ - `npm run build` (if build/runtime behavior is affected)
157
+ 3. Include a short summary:
158
+ - what changed
159
+ - why it changed
160
+ - risk/impact (especially CSP/env/analytics)
161
+ - any follow-ups or TODOs
162
+
163
+ If tests are flaky, call it out explicitly and propose stabilization steps
164
+ rather than masking failures.
165
+
166
+ ---
167
+
168
+ ## Notes for Cloud / Ephemeral Runners
169
+
170
+ Many agents run in ephemeral environments. To keep builds reproducible:
171
+
172
+ - Do not assume local files exist unless they are committed.
173
+ - Prefer deterministic commands (`npm ci` when appropriate to lockfile policy).
174
+ - Avoid relying on interactive prompts.
175
+ - If environment variables are required, document them and provide safe defaults
176
+ where possible.
177
+
178
+ ---
179
+
180
+ ## References
181
+
182
+ - `CLAUDE.md` β€” authoritative AI guidance and deeper repository context.
package/CHANGELOG.md CHANGED
@@ -24,6 +24,74 @@ version increments reflecting both user-visible and operational impact.
24
24
 
25
25
  ---
26
26
 
27
+ ## [1.26.4] - 2026-01-24
28
+
29
+ ### Added
30
+
31
+ - Added `AGENTS.md` to provide operational, tool-neutral guidance for automated agents.
32
+
33
+ ### Changed
34
+
35
+ - **Workflow tooling updates** to keep CI aligned with upstream releases:
36
+ - `npm` upgraded to `11.8.0` across build/test/publish workflows.
37
+ - `actions/checkout` `v5` β†’ `v6`, `actions/upload-artifact` `v4` β†’ `v6`, and `actions/github-script` `v7` β†’ `v8`.
38
+ - Restored Node.js/npm version logging in `publish-test` workflow jobs.
39
+ - **Documentation note added** in `CLAUDE.md` to point automation tools to `AGENTS.md`.
40
+ - **Playwright E2E stabilization** (Firefox + SvelteKit SPA navigation):
41
+ - Updated the shared navigation helper (`tests/e2e/shared/helpers.js`) to prefer SPA-safe URL-change waiting (polling assertions) over navigation lifecycle events, improving Firefox stability.
42
+ - Strengthened the desktop β€œAbout link” test (`tests/e2e/app.spec.js`) with a stable `/about` page marker assertion (`"Security, with Intent"`) to reduce intermittent flakes.
43
+ - Refreshed timestamp for root route in `static/sitemap.xml`.
44
+ - Updated generator metadata in `src/app.html` to reflect **SvelteKit 2.50.1**.
45
+ - **Project version bumped** to `v1.26.4`.
46
+ - Updated dependencies:
47
+ - `@sveltejs/adapter-vercel` `^6.3.0` β†’ `^6.3.1`
48
+ - `@sveltejs/kit` `2.50.0` β†’ `2.50.1`
49
+ - `@vitest/coverage-v8` `4.0.17` β†’ `4.0.18`
50
+ - `svelte` `5.48.0` β†’ `5.48.2`
51
+ - `vite-tsconfig-paths` `^6.0.4` β†’ `^6.0.5`
52
+ - `vitest` `4.0.17` β†’ `4.0.18`
53
+ - `@playwright/test` `^1.57.0` β†’ `^1.58.0`
54
+ - `eslint-plugin-jsdoc` `^62.3.0` β†’ `^62.4.1`
55
+ - `globals` `^17.0.0` β†’ `^17.1.0`
56
+ - `playwright` `^1.57.0` β†’ `^1.58.0`
57
+ - `posthog-js` `^1.334.0` β†’ `^1.335.2`
58
+
59
+ ---
60
+
61
+ ## [1.26.3] - 2026-01-21
62
+
63
+ ### Added
64
+
65
+ - **Codex-aware analytics guard** in `src/lib/stores/posthog.js` to explicitly skip PostHog initialization when the application is executed by automation or AI-assisted tooling.
66
+ This prevents analytics side effects during non-interactive builds, cloud executions, and AI-driven analysis while preserving normal production behavior.
67
+ - **`.env.codex` environment configuration** to support Codex and similar automation tools.
68
+ This file defines a controlled, non-interactive execution context that mirrors production build semantics without enabling analytics or requiring secrets, enabling safe use of cloud-based AI and CI-style tooling.
69
+ - **`CLAUDE.md` project guidance file** to provide persistent, repository-level instructions for Claude Code and other AI-assisted development tools.
70
+ The file establishes clear expectations and constraints for AI usage, including:
71
+ - **AI guardrails** that prohibit changes to security posture, environment detection logic, deployment assumptions, or analytics behavior without explicit human approval.
72
+ - An explicit **Allowed AI Uses** section defining safe, permitted activities such as code comprehension, incremental feature development, bug fixing, testing, and documentation updates.
73
+
74
+ ### Changed
75
+
76
+ - **Project version bumped** to `v1.26.3`.
77
+ - **Dependency updates** to incorporate upstream fixes, improvements, and compatibility updates:
78
+ - `prettier` `3.8.0` β†’ `3.8.1`
79
+ - `eslint-plugin-jsdoc` `^62.0.1` β†’ `^62.3.0`
80
+ - `lightningcss` `^1.30.2` β†’ `^1.31.1`
81
+ - `posthog-js` `^1.327.0` β†’ `^1.334.0`
82
+ - `svelte` `5.46.4` β†’ `5.48.0`
83
+
84
+ ### Security
85
+
86
+ - **Updated transitive dependency override** to remediate a reported vulnerability:
87
+ - `tar` `7.5.3` β†’ `7.5.6`
88
+ _(addresses CVE-2026-23950)_
89
+ - **Added transitive dependency override** to mitigate a reported vulnerability:
90
+ - `lodash` pinned to `4.17.23`
91
+ _(addresses CVE-2025-13465)_
92
+
93
+ ---
94
+
27
95
  ## [1.26.2] - 2026-01-17
28
96
 
29
97
  ### Changed
@@ -2243,7 +2311,9 @@ This enables analytics filtering and CSP hardening for the audit environment.
2243
2311
 
2244
2312
  <!-- Link references -->
2245
2313
 
2246
- [Unreleased]: https://github.com/netwk-pro/netwk-pro.github.io/compare/v1.26.2...HEAD
2314
+ [Unreleased]: https://github.com/netwk-pro/netwk-pro.github.io/compare/v1.26.4...HEAD
2315
+ [1.26.4]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.26.4
2316
+ [1.26.3]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.26.3
2247
2317
  [1.26.2]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.26.2
2248
2318
  [1.26.1]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.26.1
2249
2319
  [1.26.0]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.26.0
package/CLAUDE.md ADDED
@@ -0,0 +1,332 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ For tool-neutral operational guidance for automated agents (e.g., Codex, CI bots), see `AGENTS.md`.
6
+
7
+ <!-- markdownlint-disable -->
8
+
9
+ ## Project Overview
10
+
11
+ This is a **SvelteKit-based web presence** for Network Pro Strategies, deployed via Vercel. The codebase emphasizes security, privacy, and maintainability, and is distributed as both a production website and an npm package (`@networkpro/web`). It includes Progressive Web App (PWA) functionality with a custom service worker, strict Content Security Policy (CSP) configuration, and comprehensive testing.
12
+
13
+ ## AI Guardrails
14
+
15
+ This repository may be worked on using AI-assisted tools (e.g., Claude Code). When doing so, the following guardrails apply:
16
+
17
+ - **Do not introduce new environment modes** or alter environment-detection logic (`src/lib/utils/env.js`) without explicit human approval.
18
+ - **Do not weaken security posture**: CSP rules, analytics gating, service worker exclusions, and audit-mode behavior must not be relaxed for convenience.
19
+ - **Do not invent or assume CI/CD workflows**: Deployment behavior must match existing infrastructure (Vercel for production, Netlify for audit via branch-scoped workflow).
20
+ - **Do not add or modify analytics, telemetry, or external network calls** without confirming consent and environment gating logic.
21
+ - **Do not refactor for style or abstraction alone** if it obscures intent, security checks, or explicit control flow.
22
+ - **Do not commit secrets or sensitive data**; environment files are strictly separated by purpose.
23
+ - **Prefer explicit, readable code over "clever" optimizations**, especially in security- or environment-related paths.
24
+
25
+ If a change would materially affect security, deployment behavior, environment resolution, or privacy guarantees, **pause and ask for confirmation** before proceeding.
26
+
27
+ AI tools should treat this file (`CLAUDE.md`) as authoritative guidance and defer to existing documentation and code comments where conflicts arise.
28
+
29
+ ## Allowed AI Uses
30
+
31
+ AI-assisted tools may be used in this repository for the following purposes:
32
+
33
+ - **Code comprehension and explanation**: Explaining existing logic, security controls, environment detection, or architectural decisions.
34
+ - **Incremental feature development**: Implementing new features or routes that follow established patterns and respect existing constraints.
35
+ - **Bug fixing and debugging**: Identifying defects, edge cases, or test failures and proposing targeted fixes.
36
+ - **Test creation and improvement**: Writing or extending unit tests, integration tests, and E2E tests consistent with existing testing architecture.
37
+ - **Refactoring for clarity**: Improving readability, structure, or maintainability _without altering behavior, security posture, or environment semantics_.
38
+ - **Documentation updates**: Improving README files, comments, JSDoc, and other documentation to better reflect current behavior.
39
+ - **Dependency and configuration review**: Highlighting outdated dependencies, misconfigurations, or potential risks (without making changes unilaterally).
40
+ - **Accessibility and standards compliance**: Suggesting improvements related to a11y, web standards, or best practices, subject to review.
41
+ - **Clarifying questions**: Asking for confirmation when intent, risk, or trade-offs are unclear.
42
+
43
+ AI output should be treated as **assistance, not authority**. All changes are subject to human review and approval.
44
+
45
+ ## Essential Commands
46
+
47
+ ### Development
48
+
49
+ ```bash
50
+ npm run dev # Start dev server
51
+ npm run dev:audit # Dev server in audit mode (hardened CSP, no analytics)
52
+ npm run build # Production build
53
+ npm run build:audit # Audit build (for testing hardened CSP)
54
+ npm run preview # Preview production build locally
55
+ ```
56
+
57
+ ### Testing
58
+
59
+ ```bash
60
+ npm run test:all # Run all unit tests (client + server)
61
+ npm run test:client # Run client-side unit tests (jsdom)
62
+ npm run test:server # Run server-side unit tests (node)
63
+ npm run test:watch # Watch mode for client tests
64
+ npm run test:coverage # Generate coverage reports
65
+ npm run test:e2e # Run Playwright E2E tests (with 1 retry)
66
+ npm run lhci:run # Run Lighthouse CI audits
67
+ ```
68
+
69
+ ### Linting & Formatting
70
+
71
+ ```bash
72
+ npm run lint:all # Run all linters (JS, CSS, Markdown, Prettier)
73
+ npm run lint:fix # Auto-fix ESLint issues
74
+ npm run format:fix # Auto-fix Prettier formatting
75
+ npm run lint:css # Lint CSS and Svelte styles
76
+ npm run lint:md # Lint Markdown files
77
+ ```
78
+
79
+ ### Pre-commit Verification
80
+
81
+ ```bash
82
+ npm run checkout # Full verification (type-check, tests, linting)
83
+ npm run verify # Alias for checkout
84
+ ```
85
+
86
+ ### Single Test Execution
87
+
88
+ ```bash
89
+ # Run a specific client test
90
+ npx vitest run tests/unit/client/path/to/test.test.js
91
+
92
+ # Run a specific server test
93
+ npx vitest run tests/unit/server/path/to/test.test.js
94
+
95
+ # Run a specific E2E test
96
+ npx playwright test tests/e2e/app.spec.js
97
+ ```
98
+
99
+ ## Architecture & Key Patterns
100
+
101
+ ### Environment Management
102
+
103
+ The project uses a sophisticated multi-environment setup with behavior controlled by `ENV_MODE` and `PUBLIC_ENV_MODE`:
104
+
105
+ - **`development` / `dev`**: Local development with relaxed CSP, no analytics
106
+ - **`production` / `prod`**: Full CSP enforcement, PostHog analytics enabled, CSP reporting to production endpoint
107
+ - **`audit`**: Hardened environment for security testingβ€”no analytics, no external connections, strict CSP
108
+ - **`test`**: CI/test mode with relaxed CSP for automation
109
+ - **`codex`**: Special mode for Claude Code development
110
+
111
+ **Critical**: Environment detection happens in two places:
112
+
113
+ 1. **Build-time**: Via `import.meta.env.MODE` or `PUBLIC_ENV_MODE` (baked into bundle)
114
+ 2. **Runtime**: Via hostname detection in `src/lib/utils/env.js` (e.g., `audit.netwk.pro` triggers audit mode)
115
+
116
+ The `detectEnvironment()` function in `src/lib/utils/env.js` unifies this logic and is used throughout the app.
117
+
118
+ ### Content Security Policy (CSP)
119
+
120
+ CSP headers are dynamically generated in `src/hooks.server.js` based on environment:
121
+
122
+ - **Production**: Strict CSP with `Content-Security-Policy` header, real CSP reporting endpoint
123
+ - **Audit**: Hardened CSP with no analytics domains, no CSP reporting
124
+ - **Dev/Test**: Report-only mode (`Content-Security-Policy-Report-Only`) for debugging
125
+
126
+ **Current Trade-off**: The CSP allows `unsafe-inline` for scripts and styles due to PostHog and SvelteKit limitations. Moving to nonce-based CSP is a documented future goal (see README.md).
127
+
128
+ **Probely Scanner Allowlisting**: The `hooks.server.js` includes logic to detect and bypass security checks for Probely DAST scanners using `isProbelyScanner()` from `src/lib/security/probely.js`.
129
+
130
+ ### Service Worker & PWA
131
+
132
+ The service worker is defined in `src/service-worker.js` and handles:
133
+
134
+ - Precaching of build artifacts and static files
135
+ - Runtime caching strategies (cache-first, network-first)
136
+ - Analytics domain blocking (PostHog never cached)
137
+ - Cache versioning and cleanup
138
+
139
+ **Registration**: `src/lib/registerServiceWorker.js` handles:
140
+
141
+ - SW registration and update lifecycle
142
+ - Cache cleanup (removes non-prefixed caches)
143
+ - Install prompt support (`beforeinstallprompt` event)
144
+ - Firefox localhost compatibility skip
145
+ - `?nosw` query parameter bypass via `static/disableSw.js`
146
+
147
+ ### Route Structure
148
+
149
+ - **`+page.svelte`**: Page component
150
+ - **`+page.server.js`**: Server-side page load (metadata, redirects)
151
+ - **`+layout.svelte`**: Root layout with analytics init, MetaTags, header/footer
152
+ - **`+layout.js`**: Client-side layout load (pathname detection)
153
+ - **`+server.js`**: API endpoints (e.g., `/api/mock-csp`, `/pgp/[key]`)
154
+
155
+ **Special Routes**:
156
+
157
+ - `/pgp/[key]/+server.js`: Dynamic PGP key serving with proper Content-Type headers
158
+ - `/api/mock-csp/+server.js`: Mock CSP violation reporting endpoint for dev/test
159
+ - `/relay-[slug]/[...catchall]/+server.js`: Dynamic redirect handler
160
+
161
+ ### Component Organization
162
+
163
+ ```
164
+ src/lib/
165
+ β”œβ”€β”€ components/ # Reusable Svelte components
166
+ β”‚ β”œβ”€β”€ layout/ # Header, Footer
167
+ β”‚ └── foss/ # FOSS-specific components
168
+ β”œβ”€β”€ pages/ # Page-specific content components (e.g., AboutContent.svelte)
169
+ β”œβ”€β”€ data/ # Static data (fossData.js, pgpKeys.js)
170
+ β”œβ”€β”€ stores/ # Svelte stores (posthog.js, trackingPreferences.js)
171
+ β”œβ”€β”€ utils/ # Helper utilities (env.js, utm.js, purify.js)
172
+ β”œβ”€β”€ types/ # Type definitions and constants
173
+ β”œβ”€β”€ styles/ # Global CSS
174
+ └── security/ # Security utilities (probely.js)
175
+ ```
176
+
177
+ **Import Pattern**: Use `$lib` alias for all internal imports (configured in `jsconfig.json` via `vite-tsconfig-paths`).
178
+
179
+ ### Analytics & Tracking
180
+
181
+ PostHog is initialized in `src/lib/stores/posthog.js` and conditionally loaded based on:
182
+
183
+ - Environment (disabled in audit, test, dev)
184
+ - User consent (tracked in `trackingPreferences.js` store)
185
+ - Browser support
186
+
187
+ **Key Functions**:
188
+
189
+ - `initPostHog()`: Initializes PostHog with consent checking
190
+ - `capture(event)`: Wrapper for PostHog event capture
191
+ - `showReminder`: Svelte store for tracking consent banner state
192
+
193
+ Analytics initialization happens in `src/lib/utils/initAnalytics.js`, called from `+layout.svelte`.
194
+
195
+ ### Testing Architecture
196
+
197
+ **Unit Tests**: Split into client (jsdom) and server (node) contexts with separate Vitest configs:
198
+
199
+ - `tests/unit/client/`: Browser-environment tests (components, client utils)
200
+ - `tests/unit/server/`: Node-environment tests (server utils, API endpoints)
201
+ - `tests/unit/server/internal/auditCoverage.test.js`: Warns about untested source files
202
+
203
+ **E2E Tests**: Playwright tests in `tests/e2e/`:
204
+
205
+ - `app.spec.js`: Desktop and mobile route tests
206
+ - `mobile.spec.js`: Mobile-specific assertions
207
+ - `shared/helpers.js`: Shared test utilities (viewport helpers, element getters)
208
+
209
+ **Coverage Audit**: The project includes a coverage audit that warns (but doesn't fail) when source files lack corresponding unit tests.
210
+
211
+ ## Configuration Files
212
+
213
+ - **`svelte.config.js`**: SvelteKit config with Vercel adapter, prerender error handling
214
+ - **`vite.config.js`**: Vite config with SvelteKit, LightningCSS, devtools-json plugins
215
+ - **`vitest.config.client.js`**: Client-side unit test config (jsdom environment)
216
+ - **`vitest.config.server.js`**: Server-side unit test config (node environment)
217
+ - **`playwright.config.js`**: E2E test config (Chromium, Firefox, WebKit)
218
+ - **`.lighthouserc.cjs`**: Lighthouse CI audit configuration
219
+ - **`postcss.config.cjs`**: PostCSS with autoprefixer
220
+ - **`vercel.json`**: Vercel deployment config
221
+
222
+ ## Development Workflows
223
+
224
+ ### Adding a New Route
225
+
226
+ 1. Create `src/routes/your-route/+page.svelte`
227
+ 2. Create `src/routes/your-route/+page.server.js` for metadata:
228
+ ```javascript
229
+ export function load() {
230
+ return {
231
+ meta: {
232
+ title: 'Your Page Title',
233
+ description: 'Your page description',
234
+ },
235
+ };
236
+ }
237
+ ```
238
+ 3. Add corresponding E2E test in `tests/e2e/app.spec.js`
239
+ 4. Update sitemap at `static/sitemap.xml` if needed
240
+
241
+ ### Adding a New Component
242
+
243
+ 1. Create component in `src/lib/components/YourComponent.svelte`
244
+ 2. Export from `src/lib/components/index.js` if it's shared
245
+ 3. Add unit test in `tests/unit/client/components/YourComponent.test.js`
246
+ 4. Use `$lib/components` alias for imports
247
+
248
+ ### Modifying CSP
249
+
250
+ 1. Edit `src/hooks.server.js` and update `cspDirectives` array
251
+ 2. Test in audit mode: `npm run dev:audit`
252
+ 3. Check CSP violations in browser console or `/api/mock-csp` logs
253
+ 4. Update tests if needed
254
+
255
+ ### Adding Analytics Events
256
+
257
+ 1. Import `capture` from `$lib/stores/posthog`
258
+ 2. Call `capture('event_name', { properties })` in client-side code
259
+ 3. Events are automatically gated by consent and environment checks
260
+
261
+ ## Important Constraints
262
+
263
+ ### Security Considerations
264
+
265
+ - **Never commit sensitive data**: Use `.env` for local secrets, never `.env.template`
266
+ - **CSP compliance**: All inline scripts/styles must work with `unsafe-inline` or be refactored for nonces
267
+ - **Service worker**: Analytics domains (PostHog) are explicitly excluded from SW caching
268
+ - **PGP keys**: `.asc` files in `static/pgp/` are served directly, not precached
269
+
270
+ ### Code Quality Standards
271
+
272
+ - **No emojis** in commit messages or code comments unless explicitly requested
273
+ - **Copyright headers** required on all source files
274
+ - **ESLint + Prettier** enforced via pre-commit hooks
275
+ - **Stylelint** for CSS/Svelte style validation
276
+ - **JSDoc** required for exported functions
277
+
278
+ ### Build Requirements
279
+
280
+ - **Node.js**: >= 22.0.0, < 25
281
+ - **npm**: >= 10.0.0, < 12
282
+ - Enforced via `engines` in `package.json` and `scripts/checkNode.js`
283
+
284
+ ### Testing Requirements
285
+
286
+ - Unit tests should use appropriate environment (client vs. server)
287
+ - E2E tests automatically retry once to reduce flakiness
288
+ - Coverage audit warns about untested files but doesn't fail CI
289
+
290
+ ## Common Gotchas
291
+
292
+ 1. **Service Worker Caching**: Use `?nosw` query param to bypass SW for testing
293
+ 2. **Environment Detection**: Remember that `audit.netwk.pro` hostname overrides build mode
294
+ 3. **CSP Violations**: Check browser console in dev mode; violations are logged to `/api/mock-csp`
295
+ 4. **PostHog Initialization**: Happens asynchronously; use `$isInitialized` store to check status
296
+ 5. **Static Asset Imports**: Use Vite's `import` syntax (e.g., `import logo from '$lib/img/logo.png'`)
297
+ 6. **Prerendering**: Some routes are prerendered at build time; check `svelte.config.js` error handlers
298
+
299
+ ## Debugging Tips
300
+
301
+ - **Enable debug mode**: Add `?debug=true` to URL for verbose console logs
302
+ - **Disable service worker**: Add `?nosw` to URL to bypass SW caching
303
+ - **Check environment**: Use `detectEnvironment()` in any file to see current env flags
304
+ - **View CSP violations**: Check `/api/mock-csp` endpoint logs in dev mode
305
+ - **Playwright UI mode**: Run `npx playwright test --ui` for interactive debugging
306
+
307
+ ## Deployment Environments
308
+
309
+ - **Production**
310
+ - URL: `https://netwk.pro`
311
+ - Hosting: **Vercel**
312
+ - Deployment model: Automatic builds and deployments triggered by merges to `master`
313
+ - CI: Managed by Vercel (not GitHub Actions)
314
+
315
+ - **Audit**
316
+ - URL: `https://audit.netwk.pro`
317
+ - Hosting: **Netlify**
318
+ - Purpose: Hardened security environment (strict CSP, no analytics, no external reporting)
319
+ - Deployment model:
320
+ - Built and deployed via a GitHub Actions workflow
321
+ - Workflow file: `.github/workflows/deploy-audit-netlify.yml`
322
+ - Workflow exists **only on the `audit-netlify` branch**
323
+ - Deployments are intentionally decoupled from production
324
+
325
+ - **Preview**
326
+ - Hosting: Vercel
327
+ - Trigger: Pull requests and non-`master` branches
328
+ - Purpose: Ephemeral previews for review and testing
329
+
330
+ **Note**: There is no single CI/CD pipeline shared by all environments. Production relies on Vercel’s native build system, while the audit environment uses a dedicated, branch-scoped GitHub Actions workflow.
331
+
332
+ <!-- cspell:ignore prerender precached Prerendering prerendered -->
package/LICENSE.md CHANGED
@@ -6,11 +6,11 @@ SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
6
6
  This file is part of Network Pro.
7
7
  ====================================================================== -->
8
8
 
9
+ <a name="top"></a>
10
+
9
11
  <sup>[SPDX-License-Identifier](https://spdx.dev/learn/handling-license-info/):
10
12
  `CC-BY-4.0 OR GPL-3.0-or-later`</sup>
11
13
 
12
- <a name="top"></a>
13
-
14
14
  # Legal, Copyright, and Licensing
15
15
 
16
16
  **Network Pro Strategies**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@networkpro/web",
3
3
  "private": false,
4
- "version": "1.26.2",
4
+ "version": "1.26.4",
5
5
  "description": "Locking Down Networks, Unlocking Confidenceβ„’ | Security, Networking, Privacy β€” Network Pro Strategies",
6
6
  "keywords": [
7
7
  "advocacy",
@@ -43,6 +43,8 @@
43
43
  "build": "vite build --mode production",
44
44
  "build:audit": "vite build --mode audit",
45
45
  "build:vercel": "vercel build",
46
+ "build:codex": "vite build --mode codex",
47
+ "dev:codex": "vite dev --mode codex",
46
48
  "preview": "vite preview",
47
49
  "css:bundle": "node scripts/bundleCss.js",
48
50
  "prepare": "svelte-kit sync && npx simple-git-hooks || echo ''",
@@ -88,38 +90,38 @@
88
90
  },
89
91
  "dependencies": {
90
92
  "dompurify": "^3.3.1",
91
- "posthog-js": "^1.327.0",
93
+ "posthog-js": "^1.335.2",
92
94
  "semver": "^7.7.3",
93
- "svelte": "5.46.4"
95
+ "svelte": "5.48.2"
94
96
  },
95
97
  "devDependencies": {
96
98
  "@eslint/compat": "^2.0.1",
97
99
  "@eslint/js": "^9.39.2",
98
100
  "@lhci/cli": "^0.15.1",
99
- "@playwright/test": "^1.57.0",
101
+ "@playwright/test": "^1.58.0",
100
102
  "@sveltejs/adapter-netlify": "^5.2.4",
101
- "@sveltejs/adapter-vercel": "^6.3.0",
102
- "@sveltejs/kit": "2.50.0",
103
+ "@sveltejs/adapter-vercel": "^6.3.1",
104
+ "@sveltejs/kit": "2.50.1",
103
105
  "@sveltejs/vite-plugin-svelte": "^6.2.4",
104
106
  "@testing-library/jest-dom": "^6.9.1",
105
107
  "@testing-library/svelte": "^5.3.1",
106
- "@vitest/coverage-v8": "4.0.17",
108
+ "@vitest/coverage-v8": "4.0.18",
107
109
  "autoprefixer": "^10.4.23",
108
110
  "browserslist": "^4.28.1",
109
111
  "eslint": "^9.39.2",
110
112
  "eslint-config-prettier": "^10.1.8",
111
- "eslint-plugin-jsdoc": "^62.0.1",
113
+ "eslint-plugin-jsdoc": "^62.4.1",
112
114
  "eslint-plugin-svelte": "^3.14.0",
113
- "globals": "^17.0.0",
115
+ "globals": "^17.1.0",
114
116
  "globby": "^16.1.0",
115
117
  "jsdom": "27.4.0",
116
- "lightningcss": "^1.30.2",
118
+ "lightningcss": "^1.31.1",
117
119
  "markdownlint": "^0.40.0",
118
120
  "markdownlint-cli2": "0.20.0",
119
121
  "npm-run-all": "^4.1.5",
120
- "playwright": "^1.57.0",
122
+ "playwright": "^1.58.0",
121
123
  "postcss": "^8.5.6",
122
- "prettier": "3.8.0",
124
+ "prettier": "3.8.1",
123
125
  "prettier-plugin-svelte": "^3.4.1",
124
126
  "simple-git-hooks": "^2.13.1",
125
127
  "stylelint": "^17.0.0",
@@ -133,15 +135,16 @@
133
135
  "vite": "^7.3.1",
134
136
  "vite-plugin-devtools-json": "^1.0.0",
135
137
  "vite-plugin-lightningcss": "^0.0.5",
136
- "vite-tsconfig-paths": "^6.0.4",
137
- "vitest": "4.0.17"
138
+ "vite-tsconfig-paths": "^6.0.5",
139
+ "vitest": "4.0.18"
138
140
  },
139
141
  "overrides": {
140
142
  "cookie": "^1.0.0",
141
143
  "glob": "^11.1.0",
142
144
  "js-yaml": "^4.1.1",
145
+ "lodash": "^4.17.23",
143
146
  "qs": "^6.14.1",
144
- "tar": "^7.5.3",
147
+ "tar": "^7.5.6",
145
148
  "tmp": "^0.2.4"
146
149
  }
147
150
  }
package/src/app.html CHANGED
@@ -53,7 +53,7 @@
53
53
  content="bx4ham0zkpvzztzu213bhpt76m9siq" />
54
54
  <!-- cspell:enable -->
55
55
 
56
- <meta name="generator" content="SvelteKit 2.50.0" />
56
+ <meta name="generator" content="SvelteKit 2.50.1" />
57
57
 
58
58
  <script src="/disableSw.js"></script>
59
59
 
@@ -49,6 +49,15 @@ export async function initPostHog() {
49
49
  const { isAudit, isDebug, isDev, isTest, mode, effective } =
50
50
  detectEnvironment();
51
51
 
52
+ const isCodex =
53
+ import.meta.env.PUBLIC_CODEX === 'true' || import.meta.env.CODEX === 'true';
54
+
55
+ // πŸ€– Skip analytics entirely in Codex environments
56
+ if (isCodex) {
57
+ console.info('[PostHog] Skipping analytics (Codex environment).');
58
+ return;
59
+ }
60
+
52
61
  // 🌐 Hybrid hostname + environment guard
53
62
  const host = window.location.hostname;
54
63
  const isAuditHost = /(^|\.)audit\.netwk\.pro$/i.test(host);
@@ -1,5 +1,5 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
- <!-- Sitemap last updated 2026-01-11 -->
2
+ <!-- Sitemap last updated 2026-01-24 -->
3
3
 
4
4
  <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
5
5
 
@@ -7,7 +7,7 @@
7
7
 
8
8
  <loc>https://netwk.pro</loc>
9
9
 
10
- <lastmod>2026-01-10</lastmod>
10
+ <lastmod>2026-01-24</lastmod>
11
11
 
12
12
  <changefreq>weekly</changefreq>
13
13
 
@@ -69,7 +69,10 @@ test.describe('Desktop Tests', () => {
69
69
  timeout: 60000,
70
70
  });
71
71
 
72
- await expect(page).toHaveURL(/\/about/);
72
+ // βœ… β€œready” assertion to eliminate flake (SPA + Firefox)
73
+ await expect(
74
+ page.getByRole('heading', { name: 'Security, with Intent' }),
75
+ ).toBeVisible();
73
76
  });
74
77
  }); // End Desktop Tests
75
78
 
@@ -14,6 +14,8 @@ This file is part of Network Pro.
14
14
  * @updated 2025-11-12
15
15
  */
16
16
 
17
+ import { expect } from '@playwright/test';
18
+
17
19
  const DEBUG_LOGS = false; // set to true to enable console logs
18
20
 
19
21
  /**
@@ -88,28 +90,28 @@ export function getFooter(page) {
88
90
  }
89
91
 
90
92
  /**
91
- * Click + wait for SPA or full navigation event.
93
+ * Clicks a locator and waits for a URL change (SPA-safe).
94
+ * This avoids relying on navigation lifecycle events (load/domcontentloaded),
95
+ * which can be flaky or aborted in SPA routing (notably in Firefox).
92
96
  *
93
97
  * @param {import('@playwright/test').Page} page
94
98
  * @param {import('@playwright/test').Locator} locator
95
- * @param {{ urlPattern?: string | RegExp, timeout?: number }} [options]
99
+ * @param {{ urlPattern?: RegExp, timeout?: number }} [options]
100
+ * @returns {Promise<void>}
96
101
  */
97
102
  export async function clickAndWaitForNavigation(page, locator, options = {}) {
98
103
  const { urlPattern = /\/.*/, timeout = 60000 } = options;
99
104
 
100
105
  await locator.scrollIntoViewIfNeeded();
101
- await locator.waitFor({ state: 'visible', timeout: 60000 });
106
+ await locator.waitFor({ state: 'visible', timeout });
102
107
 
103
108
  const previousURL = page.url();
104
109
 
105
- const [, newURL] = await Promise.all([
106
- page.waitForURL(
107
- (url) =>
108
- url.toString() !== previousURL && urlPattern.test(url.toString()),
109
- { timeout },
110
- ),
111
- locator.click().then(() => page.url()),
112
- ]);
110
+ await locator.click();
111
+
112
+ // SPA-stable URL wait (polling) β€” does not depend on navigation lifecycle
113
+ await expect(page).toHaveURL(urlPattern, { timeout });
113
114
 
115
+ const newURL = page.url();
114
116
  console.log(`βœ… Navigation from ${previousURL} β†’ ${newURL}`);
115
117
  }