Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -220,14 +220,14 @@ jobs:
zip -r ../missionpulse-ci.zip .

- name: Upload build directory artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: chrome-extension-dist
path: apps/extension/dist/
retention-days: 7

- name: Upload extension ZIP artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: chrome-extension-zip
path: apps/extension/missionpulse-ci.zip
Expand Down Expand Up @@ -277,7 +277,7 @@ jobs:
run: pnpm --filter @pulse/extension test:e2e

- name: Upload Playwright report
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
if: always()
with:
name: playwright-report
Expand All @@ -286,7 +286,7 @@ jobs:
if-no-files-found: ignore

- name: Upload Playwright test results
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
if: always()
with:
name: playwright-test-results
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/connector-health.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,15 @@ jobs:

- name: Upload health report
if: always()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: connector-health-report
path: health-report.json
retention-days: 14

- name: Create issue on failure
if: failure()
uses: actions/github-script@v7
uses: actions/github-script@v9
with:
script: |
const fs = require('node:fs');
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ jobs:

- name: Create GitHub Release
if: ${{ !inputs.dry_run }}
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@v3
with:
name: MissionPulse v${{ steps.version.outputs.version }}
body: |
Expand All @@ -179,7 +179,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Upload extension ZIP artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: missionpulse-zip-${{ steps.version.outputs.version }}
path: apps/extension/missionpulse-${{ steps.version.outputs.version }}.zip
Expand All @@ -199,13 +199,13 @@ jobs:

steps:
- name: Download extension ZIP artifact
uses: actions/download-artifact@v4
uses: actions/download-artifact@v8
with:
name: missionpulse-zip-${{ needs.build-and-release.outputs.version }}
path: ./

- name: Publish to Chrome Web Store
uses: mnao305/chrome-extension-upload@v5.0.0
uses: mnao305/chrome-extension-upload@v6.0.0
with:
file-path: missionpulse-${{ needs.build-and-release.outputs.version }}.zip
extension-id: ${{ secrets.CHROME_EXTENSION_ID }}
Expand Down
16 changes: 8 additions & 8 deletions apps/dashboard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,19 @@
"dependencies": {
"@pulse/domain": "workspace:*",
"@pulse/ui": "workspace:*",
"@supabase/ssr": "^0.6.1",
"@supabase/supabase-js": "^2.106.1",
"@vercel/microfrontends": "^2.3.3",
"svelte": "^5.55.9"
"@supabase/ssr": "^0.12.0",
"@supabase/supabase-js": "^2.110.0",
"@vercel/microfrontends": "^2.3.6",
"svelte": "^5.56.4"
},
"devDependencies": {
"@playwright/test": "^1.59.1",
"@playwright/test": "^1.61.1",
"@pulse/tsconfig": "workspace:*",
"@sveltejs/adapter-vercel": "^6.3.2",
"@sveltejs/kit": "^2.61.1",
"@sveltejs/kit": "^2.69.1",
"@sveltejs/vite-plugin-svelte": "^5.1.1",
"@tailwindcss/vite": "^4.0.0",
"svelte-check": "^4.0.0",
"@tailwindcss/vite": "^4.3.2",
"svelte-check": "^4.7.1",
"typescript": "^5.7.0",
"vite": "^6.4.3",
"vitest": "^3.2.6"
Expand Down
28 changes: 14 additions & 14 deletions apps/extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,32 +28,32 @@
"dependencies": {
"@pulse/domain": "workspace:*",
"@pulse/ui": "workspace:*",
"@supabase/supabase-js": "^2.106.1",
"@supabase/supabase-js": "^2.110.0",
"lucide-svelte": "^0.460.0",
"svelte": "^5.55.9",
"svelte": "^5.56.4",
"zod": "^3.23.0"
},
"devDependencies": {
"@crxjs/vite-plugin": "^2.0.0-beta.28",
"@crxjs/vite-plugin": "^2.7.1",
"@eslint/js": "^9.39.4",
"@playwright/test": "^1.49.0",
"@playwright/test": "^1.61.1",
"@pulse/tsconfig": "workspace:*",
"@sveltejs/vite-plugin-svelte": "^5.1.1",
"@tailwindcss/vite": "^4.0.0",
"@types/chrome": "^0.0.287",
"@tailwindcss/vite": "^4.3.2",
"@types/chrome": "^0.2.2",
"@types/node": "^22.0.0",
"@vitest/coverage-v8": "^3.2.6",
"eslint": "^9.0.0",
"eslint": "^10.6.0",
"eslint-plugin-svelte": "^2.45.0",
"fake-indexeddb": "^6.2.5",
"globals": "^17.4.0",
"jsdom": "^28.1.0",
"prettier": "^3.4.0",
"prettier-plugin-svelte": "^3.3.0",
"tailwindcss": "^4.0.0",
"tsx": "^4.19.0",
"globals": "^17.7.0",
"jsdom": "^29.1.1",
"prettier": "^3.9.4",
"prettier-plugin-svelte": "^4.1.1",
"tailwindcss": "^4.3.2",
"tsx": "^4.23.0",
"typescript": "^5.7.0",
"typescript-eslint": "^8.58.1",
"typescript-eslint": "^8.62.1",
"vite": "^6.4.3",
"vitest": "^3.2.6"
}
Expand Down
3 changes: 1 addition & 2 deletions apps/extension/src/dev/chrome-stubs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -469,8 +469,7 @@ function createChromeStubs() {
case 'GET_TJM_ANALYSIS': {
const history = storage.tjm_history as TJMHistory | undefined;
const payload = message.payload as
| { profileStacks?: string[]; region?: TJMRegion }
| undefined;
{ profileStacks?: string[]; region?: TJMRegion } | undefined;
const normalizedStacks =
payload?.profileStacks && payload.profileStacks.length > 0
? new Set(payload.profileStacks.map((stack) => stack.toLowerCase().trim()))
Expand Down
35 changes: 17 additions & 18 deletions apps/extension/src/lib/core/connectors/freework-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,23 +120,22 @@ export function parseFreeWorkAPI(data: FreeWorkApiResponse, now: Date): Mission[

return data['hydra:member']
.filter((p) => isFreelanceContract(p.contracts ?? []))
.map(
(p): Mission =>
createMission({
id: `fw-${p.id}`,
title: p.title,
client: p.company?.name ?? null,
description: p.description ?? '',
stack: (p.skills ?? []).map((s) => s.name),
tjm: p.minDailySalary ?? p.maxDailySalary ?? null,
location: p.location?.label ?? p.location?.shortLabel ?? null,
remote: mapRemoteMode(p.remoteMode),
duration: formatDuration(p.durationValue, p.durationPeriod),
url: buildJobUrl(p.slug, p.job?.slug ?? null),
source: SOURCE,
scrapedAt: now,
seniority: mapExperienceLevel(p.experienceLevel),
publishedAt: p.publishedAt ?? null,
})
.map((p): Mission =>
createMission({
id: `fw-${p.id}`,
title: p.title,
client: p.company?.name ?? null,
description: p.description ?? '',
stack: (p.skills ?? []).map((s) => s.name),
tjm: p.minDailySalary ?? p.maxDailySalary ?? null,
location: p.location?.label ?? p.location?.shortLabel ?? null,
remote: mapRemoteMode(p.remoteMode),
duration: formatDuration(p.durationValue, p.durationPeriod),
url: buildJobUrl(p.slug, p.job?.slug ?? null),
source: SOURCE,
scrapedAt: now,
seniority: mapExperienceLevel(p.experienceLevel),
publishedAt: p.publishedAt ?? null,
})
);
}
6 changes: 1 addition & 5 deletions apps/extension/src/lib/core/errors/app-error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,7 @@ export interface ValidationError extends BaseAppError {

/** Union discriminating de toutes les erreurs applicatives */
export type AppError =
| NetworkError
| StorageError
| ParsingError
| ConnectorError
| ValidationError;
NetworkError | StorageError | ParsingError | ConnectorError | ValidationError;

// ============================================================================
// Type guards
Expand Down
4 changes: 1 addition & 3 deletions apps/extension/src/lib/core/profile-extractors/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,7 @@ export interface CanonicalCandidateProfileDraft {
}

export type ProfileExtractorParseErrorCode =
| 'malformed_payload'
| 'unsupported_source'
| 'dom_changed';
'malformed_payload' | 'unsupported_source' | 'dom_changed';

export interface ProfileExtractorParseError {
code: ProfileExtractorParseErrorCode;
Expand Down
8 changes: 1 addition & 7 deletions apps/extension/src/lib/core/profile/profile-impact.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
import type { UserProfile } from '../types/profile';

export type ProfileImpactFieldId =
| 'keywords'
| 'tjm-min'
| 'remote'
| 'location'
| 'job-title'
| 'tjm-max'
| 'first-name';
'keywords' | 'tjm-min' | 'remote' | 'location' | 'job-title' | 'tjm-max' | 'first-name';

export type ProfileImpactInput = Pick<
UserProfile,
Expand Down
13 changes: 2 additions & 11 deletions apps/extension/src/lib/core/sync/connected-dashboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,10 @@ import {
} from '../types/alert-preferences';

export type SyncEntity =
| 'missions'
| 'applications'
| 'candidate_profile'
| 'connector_health'
| 'alert_preferences';
'missions' | 'applications' | 'candidate_profile' | 'connector_health' | 'alert_preferences';

export type ConnectorHealthSyncStatus =
| 'ready'
| 'needs_permission'
| 'needs_session'
| 'blocked'
| 'error'
| 'syncing';
'ready' | 'needs_permission' | 'needs_session' | 'blocked' | 'error' | 'syncing';

export interface MissionUpsertRow {
user_id: string;
Expand Down
7 changes: 1 addition & 6 deletions apps/extension/src/lib/core/types/mission.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,7 @@ import type { SeniorityLevel } from './profile';
import type { ScoreBreakdown } from './score';

export type MissionSource =
| 'free-work'
| 'lehibou'
| 'hiway'
| 'collective'
| 'cherry-pick'
| 'malt';
'free-work' | 'lehibou' | 'hiway' | 'collective' | 'cherry-pick' | 'malt';

export type RemoteType = 'full' | 'hybrid' | 'onsite';

Expand Down
6 changes: 1 addition & 5 deletions apps/extension/src/lib/shell/messaging/error-boundary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,7 @@ import { validateMessage } from './schemas';
// ============================================================================

export type ErrorCategory =
| 'VALIDATION_ERROR'
| 'CONNECTOR_ERROR'
| 'STORAGE_ERROR'
| 'PAYLOAD_TOO_LARGE'
| 'UNKNOWN';
'VALIDATION_ERROR' | 'CONNECTOR_ERROR' | 'STORAGE_ERROR' | 'PAYLOAD_TOO_LARGE' | 'UNKNOWN';

export interface BoundaryErrorResponse {
success: false;
Expand Down
4 changes: 2 additions & 2 deletions apps/extension/src/lib/shell/storage/favorites.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const HIDDEN_KEY = 'hiddenMissions';

export async function getFavorites(): Promise<Record<string, number>> {
const result = await chrome.storage.local.get([FAVORITES_KEY]);
return result[FAVORITES_KEY] ?? {};
return (result[FAVORITES_KEY] as Record<string, number> | undefined) ?? {};
}
Comment on lines 4 to 7

export async function saveFavorites(favorites: Record<string, number>): Promise<void> {
Expand All @@ -12,7 +12,7 @@ export async function saveFavorites(favorites: Record<string, number>): Promise<

export async function getHidden(): Promise<Record<string, number>> {
const result = await chrome.storage.local.get([HIDDEN_KEY]);
return result[HIDDEN_KEY] ?? {};
return (result[HIDDEN_KEY] as Record<string, number> | undefined) ?? {};
}
Comment on lines 13 to 16

export async function saveHidden(hidden: Record<string, number>): Promise<void> {
Expand Down
10 changes: 2 additions & 8 deletions apps/extension/src/lib/shell/storage/migration-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,7 @@ export type MigrationState =
| 'failed';

export type MigrationErrorCode =
| 'downgrade'
| 'corrupt'
| 'quota'
| 'structural_throw'
| 'data_throw'
| 'unknown';
'downgrade' | 'corrupt' | 'quota' | 'structural_throw' | 'data_throw' | 'unknown';

export interface MigrationError {
code: MigrationErrorCode;
Expand All @@ -47,8 +42,7 @@ export interface MigrationVersions {
}

export type MigrationResult =
| ({ ok: true } & MigrationVersions)
| { ok: false; code: MigrationErrorCode; message: string };
({ ok: true } & MigrationVersions) | { ok: false; code: MigrationErrorCode; message: string };

/**
* Storage keys used by the orchestrator in `chrome.storage.local`.
Expand Down
2 changes: 1 addition & 1 deletion apps/extension/src/lib/shell/storage/seen-missions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const MAX_SEEN_IDS = 2000;

export async function getSeenIds(): Promise<string[]> {
const result = await chrome.storage.local.get([STORAGE_KEY]);
return result[STORAGE_KEY] ?? [];
return (result[STORAGE_KEY] as string[] | undefined) ?? [];
}
Comment on lines 4 to 7

export async function saveSeenIds(ids: string[]): Promise<void> {
Expand Down
16 changes: 2 additions & 14 deletions apps/extension/src/lib/state/cv-experience.svelte.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,9 @@ import {
export type FeedStatus = 'loading' | 'ready' | 'error';
export type EditStatus = 'idle' | 'adding' | 'editing' | 'saving' | 'deleting' | 'error';
export type SyncStatus =
| 'idle'
| 'preparing'
| 'syncing'
| 'cancelled'
| 'synced'
| 'partial'
| 'error';
'idle' | 'preparing' | 'syncing' | 'cancelled' | 'synced' | 'partial' | 'error';
export type PlatformSyncStatus =
| 'pending'
| 'copying'
| 'done'
| 'error'
| 'auth-required'
| 'blocked'
| 'skipped';
'pending' | 'copying' | 'done' | 'error' | 'auth-required' | 'blocked' | 'skipped';

export interface CvExperienceDeps {
loadExperiences(): Promise<Experience[]>;
Expand Down
9 changes: 3 additions & 6 deletions apps/extension/src/ui/pages/FeedPage.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -272,16 +272,13 @@
let LastScanInfo: typeof import('../molecules/LastScanInfo.svelte').default | null = $state(null);
let FilterBar: typeof import('../organisms/FilterBar.svelte').default | null = $state(null);
let KeyboardShortcutsHelp:
| typeof import('../molecules/KeyboardShortcutsHelp.svelte').default
| null = $state(null);
typeof import('../molecules/KeyboardShortcutsHelp.svelte').default | null = $state(null);
let MissionInvestigationDrawer:
| typeof import('../organisms/MissionInvestigationDrawer.svelte').default
| null = $state(null);
typeof import('../organisms/MissionInvestigationDrawer.svelte').default | null = $state(null);
let MissionComparison: typeof import('../organisms/MissionComparison.svelte').default | null =
$state(null);
let ProfileRefinementBanner:
| typeof import('../molecules/ProfileRefinementBanner.svelte').default
| null = $state(null);
typeof import('../molecules/ProfileRefinementBanner.svelte').default | null = $state(null);
let ConnectorAlertBar: typeof import('../molecules/ConnectorAlertBar.svelte').default | null =
$state(null);
let FeedTourOverlay: typeof import('../molecules/FeedTourOverlay.svelte').default | null =
Expand Down
Loading
Loading