diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml
new file mode 100644
index 0000000..ae946e4
--- /dev/null
+++ b/.github/workflows/build-windows.yml
@@ -0,0 +1,150 @@
+name: Build Windows App
+
+on:
+ push:
+ branches:
+ - main
+ - 'feature/**'
+ paths-ignore:
+ - '.github/**'
+ - '!.github/workflows/build-windows.yml'
+ pull_request:
+ branches:
+ - main
+ workflow_dispatch:
+
+permissions:
+ contents: write
+
+jobs:
+ build:
+ name: Build Windows App
+ runs-on: windows-latest
+ strategy:
+ matrix:
+ arch: [x64]
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: '8.3'
+ extensions: mbstring, xml, ctype, iconv, intl, pdo_sqlite, dom, filter, gd, json, mbstring, pdo
+ tools: composer:v2
+ coverage: none
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: '22'
+
+ - name: Get version
+ id: version
+ shell: bash
+ run: |
+ VERSION=$(grep "'version' =>" config/nativephp.php | sed -E "s/.*'([0-9]+\.[0-9]+\.[0-9]+)'.*/\1/")
+ echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
+ echo "Building version: $VERSION"
+
+ - name: Cache Composer dependencies
+ uses: actions/cache@v4
+ with:
+ path: vendor
+ key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-composer-
+
+ - name: Install Composer dependencies
+ run: composer install --no-interaction --no-dev --prefer-dist --optimize-autoloader
+
+ - name: Clean npm cache and node_modules
+ shell: cmd
+ run: |
+ if exist node_modules rmdir /s /q node_modules
+ if exist package-lock.json del package-lock.json
+ npm cache clean --force
+
+ - name: Install NPM dependencies (Windows-specific)
+ shell: cmd
+ run: |
+ echo Installing npm dependencies for Windows...
+ npm install --omit=dev --no-optional
+ echo Dependencies installed successfully
+
+ - name: Copy .env file
+ run: cp .env.example .env
+
+ - name: Generate application key
+ run: php artisan key:generate
+
+ - name: Build frontend assets
+ run: npm run build
+
+ - name: Generate Ziggy routes
+ run: php artisan ziggy:generate
+
+ - name: Install Electron dependencies
+ working-directory: vendor/nativephp/electron/resources/js
+ shell: cmd
+ run: |
+ if exist node_modules rmdir /s /q node_modules
+ npm install --no-optional
+
+ - name: Rebuild Electron native modules
+ working-directory: vendor/nativephp/electron/resources/js
+ run: npx electron-rebuild
+
+ - name: Build NativePHP application
+ env:
+ NATIVEPHP_APP_VERSION: ${{ steps.version.outputs.VERSION }}
+ run: |
+ php artisan native:build win ${{ matrix.arch }}
+
+ - name: Upload artifacts
+ uses: actions/upload-artifact@v4
+ with:
+ name: Clueless-${{ steps.version.outputs.VERSION }}-win-${{ matrix.arch }}
+ path: dist/*.exe
+ retention-days: 5
+
+ release:
+ name: Create Windows Release
+ needs: build
+ runs-on: ubuntu-latest
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main'
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Get version
+ id: version
+ run: |
+ VERSION=$(grep "'version' =>" config/nativephp.php | sed -E "s/.*'([0-9]+\.[0-9]+\.[0-9]+)'.*/\1/")
+ echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
+
+ - name: Download x64 artifact
+ uses: actions/download-artifact@v4
+ with:
+ name: Clueless-${{ steps.version.outputs.VERSION }}-win-x64
+ path: ./artifacts/win-x64
+
+ - name: Upload Windows Release Assets
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ # Find the existing release for v${{ steps.version.outputs.VERSION }}
+ RELEASE_ID=$(gh api repos/${{ github.repository }}/releases/tags/v${{ steps.version.outputs.VERSION }} --jq '.id' || echo "")
+
+ if [ -z "$RELEASE_ID" ]; then
+ echo "No release found for v${{ steps.version.outputs.VERSION }}. Windows build will be added when release is created."
+ exit 0
+ fi
+
+ # Upload the Windows executables
+ gh release upload v${{ steps.version.outputs.VERSION }} \
+ ./artifacts/win-x64/Clueless-${{ steps.version.outputs.VERSION }}-win-x64.exe \
+ --clobber
\ No newline at end of file
diff --git a/app/Http/Controllers/ConversationController.php b/app/Http/Controllers/ConversationController.php
index 921f100..fa60db2 100644
--- a/app/Http/Controllers/ConversationController.php
+++ b/app/Http/Controllers/ConversationController.php
@@ -282,4 +282,44 @@ public function destroy(ConversationSession $session)
return redirect()->route('conversations.index')
->with('message', 'Conversation deleted successfully');
}
+
+ /**
+ * Update recording information for a conversation session.
+ */
+ public function updateRecording(ConversationSession $session, Request $request)
+ {
+ // No auth check needed for single-user desktop app
+
+ $validated = $request->validate([
+ 'has_recording' => 'required|boolean',
+ 'recording_path' => 'required|string',
+ 'recording_duration' => 'required|integer|min:0',
+ 'recording_size' => 'required|integer|min:0',
+ ]);
+
+ // Validate that the recording file actually exists
+ if ($validated['has_recording'] && $validated['recording_path']) {
+ if (!file_exists($validated['recording_path'])) {
+ return response()->json([
+ 'message' => 'Recording file not found at specified path',
+ ], 422);
+ }
+
+ // Verify file size matches
+ $actualSize = filesize($validated['recording_path']);
+ if ($actualSize !== $validated['recording_size']) {
+ \Log::warning('Recording file size mismatch', [
+ 'session_id' => $session->id,
+ 'expected_size' => $validated['recording_size'],
+ 'actual_size' => $actualSize,
+ ]);
+ }
+ }
+
+ $session->update($validated);
+
+ return response()->json([
+ 'message' => 'Recording information updated successfully',
+ ]);
+ }
}
diff --git a/app/Models/ConversationSession.php b/app/Models/ConversationSession.php
index d1bbea0..53d4178 100644
--- a/app/Models/ConversationSession.php
+++ b/app/Models/ConversationSession.php
@@ -31,6 +31,10 @@ class ConversationSession extends Model
'total_action_items',
'ai_summary',
'user_notes',
+ 'has_recording',
+ 'recording_path',
+ 'recording_duration',
+ 'recording_size',
];
protected $casts = [
@@ -42,6 +46,9 @@ class ConversationSession extends Model
'total_topics' => 'integer',
'total_commitments' => 'integer',
'total_action_items' => 'integer',
+ 'has_recording' => 'boolean',
+ 'recording_duration' => 'integer',
+ 'recording_size' => 'integer',
];
public function user(): BelongsTo
diff --git a/database/migrations/2025_08_05_214155_add_recording_fields_to_conversation_sessions_table.php b/database/migrations/2025_08_05_214155_add_recording_fields_to_conversation_sessions_table.php
new file mode 100644
index 0000000..cf81f93
--- /dev/null
+++ b/database/migrations/2025_08_05_214155_add_recording_fields_to_conversation_sessions_table.php
@@ -0,0 +1,31 @@
+boolean('has_recording')->default(false)->after('ended_at');
+ $table->string('recording_path')->nullable()->after('has_recording');
+ $table->integer('recording_duration')->nullable()->comment('Duration in seconds')->after('recording_path');
+ $table->bigInteger('recording_size')->nullable()->comment('Size in bytes')->after('recording_duration');
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::table('conversation_sessions', function (Blueprint $table) {
+ $table->dropColumn(['has_recording', 'recording_path', 'recording_duration', 'recording_size']);
+ });
+ }
+};
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 8f77284..8178273 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -50,8 +50,7 @@
"optionalDependencies": {
"@rollup/rollup-linux-x64-gnu": "4.9.5",
"@tailwindcss/oxide-linux-x64-gnu": "^4.0.1",
- "lightningcss-linux-x64-gnu": "^1.29.1",
- "node-mac-permissions": "^2.5.0"
+ "lightningcss-linux-x64-gnu": "^1.29.1"
}
},
"node_modules/@ampproject/remapping": {
@@ -1779,17 +1778,17 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin": {
- "version": "8.38.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.38.0.tgz",
- "integrity": "sha512-CPoznzpuAnIOl4nhj4tRr4gIPj5AfKgkiJmGQDaq+fQnRJTYlcBjbX3wbciGmpoPf8DREufuPRe1tNMZnGdanA==",
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.39.0.tgz",
+ "integrity": "sha512-bhEz6OZeUR+O/6yx9Jk6ohX6H9JSFTaiY0v9/PuKT3oGK0rn0jNplLmyFUGV+a9gfYnVNwGDwS/UkLIuXNb2Rw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/regexpp": "^4.10.0",
- "@typescript-eslint/scope-manager": "8.38.0",
- "@typescript-eslint/type-utils": "8.38.0",
- "@typescript-eslint/utils": "8.38.0",
- "@typescript-eslint/visitor-keys": "8.38.0",
+ "@typescript-eslint/scope-manager": "8.39.0",
+ "@typescript-eslint/type-utils": "8.39.0",
+ "@typescript-eslint/utils": "8.39.0",
+ "@typescript-eslint/visitor-keys": "8.39.0",
"graphemer": "^1.4.0",
"ignore": "^7.0.0",
"natural-compare": "^1.4.0",
@@ -1803,9 +1802,9 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "@typescript-eslint/parser": "^8.38.0",
+ "@typescript-eslint/parser": "^8.39.0",
"eslint": "^8.57.0 || ^9.0.0",
- "typescript": ">=4.8.4 <5.9.0"
+ "typescript": ">=4.8.4 <6.0.0"
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": {
@@ -1819,16 +1818,16 @@
}
},
"node_modules/@typescript-eslint/parser": {
- "version": "8.38.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.38.0.tgz",
- "integrity": "sha512-Zhy8HCvBUEfBECzIl1PKqF4p11+d0aUJS1GeUiuqK9WmOug8YCmC4h4bjyBvMyAMI9sbRczmrYL5lKg/YMbrcQ==",
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.39.0.tgz",
+ "integrity": "sha512-g3WpVQHngx0aLXn6kfIYCZxM6rRJlWzEkVpqEFLT3SgEDsp9cpCbxxgwnE504q4H+ruSDh/VGS6nqZIDynP+vg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/scope-manager": "8.38.0",
- "@typescript-eslint/types": "8.38.0",
- "@typescript-eslint/typescript-estree": "8.38.0",
- "@typescript-eslint/visitor-keys": "8.38.0",
+ "@typescript-eslint/scope-manager": "8.39.0",
+ "@typescript-eslint/types": "8.39.0",
+ "@typescript-eslint/typescript-estree": "8.39.0",
+ "@typescript-eslint/visitor-keys": "8.39.0",
"debug": "^4.3.4"
},
"engines": {
@@ -1840,18 +1839,18 @@
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0",
- "typescript": ">=4.8.4 <5.9.0"
+ "typescript": ">=4.8.4 <6.0.0"
}
},
"node_modules/@typescript-eslint/project-service": {
- "version": "8.38.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.38.0.tgz",
- "integrity": "sha512-dbK7Jvqcb8c9QfH01YB6pORpqX1mn5gDZc9n63Ak/+jD67oWXn3Gs0M6vddAN+eDXBCS5EmNWzbSxsn9SzFWWg==",
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.39.0.tgz",
+ "integrity": "sha512-CTzJqaSq30V/Z2Og9jogzZt8lJRR5TKlAdXmWgdu4hgcC9Kww5flQ+xFvMxIBWVNdxJO7OifgdOK4PokMIWPew==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/tsconfig-utils": "^8.38.0",
- "@typescript-eslint/types": "^8.38.0",
+ "@typescript-eslint/tsconfig-utils": "^8.39.0",
+ "@typescript-eslint/types": "^8.39.0",
"debug": "^4.3.4"
},
"engines": {
@@ -1862,18 +1861,18 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "typescript": ">=4.8.4 <5.9.0"
+ "typescript": ">=4.8.4 <6.0.0"
}
},
"node_modules/@typescript-eslint/scope-manager": {
- "version": "8.38.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.38.0.tgz",
- "integrity": "sha512-WJw3AVlFFcdT9Ri1xs/lg8LwDqgekWXWhH3iAF+1ZM+QPd7oxQ6jvtW/JPwzAScxitILUIFs0/AnQ/UWHzbATQ==",
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.39.0.tgz",
+ "integrity": "sha512-8QOzff9UKxOh6npZQ/4FQu4mjdOCGSdO3p44ww0hk8Vu+IGbg0tB/H1LcTARRDzGCC8pDGbh2rissBuuoPgH8A==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "8.38.0",
- "@typescript-eslint/visitor-keys": "8.38.0"
+ "@typescript-eslint/types": "8.39.0",
+ "@typescript-eslint/visitor-keys": "8.39.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -1884,9 +1883,9 @@
}
},
"node_modules/@typescript-eslint/tsconfig-utils": {
- "version": "8.38.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.38.0.tgz",
- "integrity": "sha512-Lum9RtSE3EroKk/bYns+sPOodqb2Fv50XOl/gMviMKNvanETUuUcC9ObRbzrJ4VSd2JalPqgSAavwrPiPvnAiQ==",
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.39.0.tgz",
+ "integrity": "sha512-Fd3/QjmFV2sKmvv3Mrj8r6N8CryYiCS8Wdb/6/rgOXAWGcFuc+VkQuG28uk/4kVNVZBQuuDHEDUpo/pQ32zsIQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1897,19 +1896,19 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "typescript": ">=4.8.4 <5.9.0"
+ "typescript": ">=4.8.4 <6.0.0"
}
},
"node_modules/@typescript-eslint/type-utils": {
- "version": "8.38.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.38.0.tgz",
- "integrity": "sha512-c7jAvGEZVf0ao2z+nnz8BUaHZD09Agbh+DY7qvBQqLiz8uJzRgVPj5YvOh8I8uEiH8oIUGIfHzMwUcGVco/SJg==",
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.39.0.tgz",
+ "integrity": "sha512-6B3z0c1DXVT2vYA9+z9axjtc09rqKUPRmijD5m9iv8iQpHBRYRMBcgxSiKTZKm6FwWw1/cI4v6em35OsKCiN5Q==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "8.38.0",
- "@typescript-eslint/typescript-estree": "8.38.0",
- "@typescript-eslint/utils": "8.38.0",
+ "@typescript-eslint/types": "8.39.0",
+ "@typescript-eslint/typescript-estree": "8.39.0",
+ "@typescript-eslint/utils": "8.39.0",
"debug": "^4.3.4",
"ts-api-utils": "^2.1.0"
},
@@ -1922,13 +1921,13 @@
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0",
- "typescript": ">=4.8.4 <5.9.0"
+ "typescript": ">=4.8.4 <6.0.0"
}
},
"node_modules/@typescript-eslint/types": {
- "version": "8.38.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.38.0.tgz",
- "integrity": "sha512-wzkUfX3plUqij4YwWaJyqhiPE5UCRVlFpKn1oCRn2O1bJ592XxWJj8ROQ3JD5MYXLORW84063z3tZTb/cs4Tyw==",
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.39.0.tgz",
+ "integrity": "sha512-ArDdaOllnCj3yn/lzKn9s0pBQYmmyme/v1HbGIGB0GB/knFI3fWMHloC+oYTJW46tVbYnGKTMDK4ah1sC2v0Kg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1940,16 +1939,16 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
- "version": "8.38.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.38.0.tgz",
- "integrity": "sha512-fooELKcAKzxux6fA6pxOflpNS0jc+nOQEEOipXFNjSlBS6fqrJOVY/whSn70SScHrcJ2LDsxWrneFoWYSVfqhQ==",
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.39.0.tgz",
+ "integrity": "sha512-ndWdiflRMvfIgQRpckQQLiB5qAKQ7w++V4LlCHwp62eym1HLB/kw7D9f2e8ytONls/jt89TEasgvb+VwnRprsw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/project-service": "8.38.0",
- "@typescript-eslint/tsconfig-utils": "8.38.0",
- "@typescript-eslint/types": "8.38.0",
- "@typescript-eslint/visitor-keys": "8.38.0",
+ "@typescript-eslint/project-service": "8.39.0",
+ "@typescript-eslint/tsconfig-utils": "8.39.0",
+ "@typescript-eslint/types": "8.39.0",
+ "@typescript-eslint/visitor-keys": "8.39.0",
"debug": "^4.3.4",
"fast-glob": "^3.3.2",
"is-glob": "^4.0.3",
@@ -1965,20 +1964,20 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "typescript": ">=4.8.4 <5.9.0"
+ "typescript": ">=4.8.4 <6.0.0"
}
},
"node_modules/@typescript-eslint/utils": {
- "version": "8.38.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.38.0.tgz",
- "integrity": "sha512-hHcMA86Hgt+ijJlrD8fX0j1j8w4C92zue/8LOPAFioIno+W0+L7KqE8QZKCcPGc/92Vs9x36w/4MPTJhqXdyvg==",
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.39.0.tgz",
+ "integrity": "sha512-4GVSvNA0Vx1Ktwvf4sFE+exxJ3QGUorQG1/A5mRfRNZtkBT2xrA/BCO2H0eALx/PnvCS6/vmYwRdDA41EoffkQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.7.0",
- "@typescript-eslint/scope-manager": "8.38.0",
- "@typescript-eslint/types": "8.38.0",
- "@typescript-eslint/typescript-estree": "8.38.0"
+ "@typescript-eslint/scope-manager": "8.39.0",
+ "@typescript-eslint/types": "8.39.0",
+ "@typescript-eslint/typescript-estree": "8.39.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -1989,17 +1988,17 @@
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0",
- "typescript": ">=4.8.4 <5.9.0"
+ "typescript": ">=4.8.4 <6.0.0"
}
},
"node_modules/@typescript-eslint/visitor-keys": {
- "version": "8.38.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.38.0.tgz",
- "integrity": "sha512-pWrTcoFNWuwHlA9CvlfSsGWs14JxfN1TH25zM5L7o0pRLhsoZkDnTsXfQRJBEWJoV5DL0jf+Z+sxiud+K0mq1g==",
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.39.0.tgz",
+ "integrity": "sha512-ldgiJ+VAhQCfIjeOgu8Kj5nSxds0ktPOSO9p4+0VDH2R2pLvQraaM5Oen2d7NxzMCm+Sn/vJT+mv2H5u6b/3fA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "8.38.0",
+ "@typescript-eslint/types": "8.39.0",
"eslint-visitor-keys": "^4.2.1"
},
"engines": {
@@ -2424,16 +2423,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/bindings": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
- "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "file-uri-to-path": "1.0.0"
- }
- },
"node_modules/birpc": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/birpc/-/birpc-2.5.0.tgz",
@@ -3054,9 +3043,9 @@
}
},
"node_modules/electron-audio-loopback": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/electron-audio-loopback/-/electron-audio-loopback-1.0.5.tgz",
- "integrity": "sha512-E/xneHrk2tLD7JntbjBJJr4HyWGaLrdGvqmoeBJZg9URbBBm2OgTEZ5TWgTkIPiAwEvAllsV+VfdBOfP4FeMkw==",
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/electron-audio-loopback/-/electron-audio-loopback-1.0.6.tgz",
+ "integrity": "sha512-QW0ogDqMpWHDAQHmQyssJ+Yh4qR3kWCP3Q4H9WuIXKwVlgkqOYGyt0v/JzbK3tBNTwfqbuHZy86kwCCajxqAdg==",
"license": "MIT",
"peerDependencies": {
"electron": ">=31.0.1"
@@ -3792,13 +3781,6 @@
"node": ">=16.0.0"
}
},
- "node_modules/file-uri-to-path": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
- "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
- "license": "MIT",
- "optional": true
- },
"node_modules/fill-range": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
@@ -4808,9 +4790,9 @@
}
},
"node_modules/marked": {
- "version": "16.1.1",
- "resolved": "https://registry.npmjs.org/marked/-/marked-16.1.1.tgz",
- "integrity": "sha512-ij/2lXfCRT71L6u0M29tJPhP0bM5shLL3u5BePhFwPELj2blMJ6GDtD7PfJhRLhJ/c2UwrK17ySVcDzy2YHjHQ==",
+ "version": "16.1.2",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-16.1.2.tgz",
+ "integrity": "sha512-rNQt5EvRinalby7zJZu/mB+BvaAY2oz3wCuCjt1RDrWNpS1Pdf9xqMOeC9Hm5adBdcV/3XZPJpG58eT+WBc0XQ==",
"license": "MIT",
"bin": {
"marked": "bin/marked.js"
@@ -5028,28 +5010,6 @@
"node": ">= 0.6"
}
},
- "node_modules/node-addon-api": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
- "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
- "license": "MIT",
- "optional": true
- },
- "node_modules/node-mac-permissions": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/node-mac-permissions/-/node-mac-permissions-2.5.0.tgz",
- "integrity": "sha512-zR8SVCaN3WqV1xwWd04XVAdzm3UTdjbxciLrZtB0Cc7F2Kd34AJfhPD4hm1HU0YH3oGUZO4X9OBLY5ijSTHsGw==",
- "hasInstallScript": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "dependencies": {
- "bindings": "^1.5.0",
- "node-addon-api": "^7.1.0"
- }
- },
"node_modules/normalize-url": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",
@@ -5138,9 +5098,9 @@
}
},
"node_modules/openai": {
- "version": "5.11.0",
- "resolved": "https://registry.npmjs.org/openai/-/openai-5.11.0.tgz",
- "integrity": "sha512-+AuTc5pVjlnTuA9zvn8rA/k+1RluPIx9AD4eDcnutv6JNwHHZxIhkFy+tmMKCvmMFDQzfA/r1ujvPWB19DQkYg==",
+ "version": "5.12.0",
+ "resolved": "https://registry.npmjs.org/openai/-/openai-5.12.0.tgz",
+ "integrity": "sha512-vUdt02xiWgOHiYUmW0Hj1Qu9OKAiVQu5Bd547ktVCiMKC1BkB5L3ImeEnCyq3WpRKR6ZTaPgekzqdozwdPs7Lg==",
"license": "Apache-2.0",
"bin": {
"openai": "bin/cli"
@@ -6357,9 +6317,9 @@
}
},
"node_modules/typescript": {
- "version": "5.8.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
- "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
+ "version": "5.9.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz",
+ "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==",
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
@@ -6370,16 +6330,16 @@
}
},
"node_modules/typescript-eslint": {
- "version": "8.38.0",
- "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.38.0.tgz",
- "integrity": "sha512-FsZlrYK6bPDGoLeZRuvx2v6qrM03I0U0SnfCLPs/XCCPCFD80xU9Pg09H/K+XFa68uJuZo7l/Xhs+eDRg2l3hg==",
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.39.0.tgz",
+ "integrity": "sha512-lH8FvtdtzcHJCkMOKnN73LIn6SLTpoojgJqDAxPm1jCR14eWSGPX8ul/gggBdPMk/d5+u9V854vTYQ8T5jF/1Q==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/eslint-plugin": "8.38.0",
- "@typescript-eslint/parser": "8.38.0",
- "@typescript-eslint/typescript-estree": "8.38.0",
- "@typescript-eslint/utils": "8.38.0"
+ "@typescript-eslint/eslint-plugin": "8.39.0",
+ "@typescript-eslint/parser": "8.39.0",
+ "@typescript-eslint/typescript-estree": "8.39.0",
+ "@typescript-eslint/utils": "8.39.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -6390,7 +6350,7 @@
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0",
- "typescript": ">=4.8.4 <5.9.0"
+ "typescript": ">=4.8.4 <6.0.0"
}
},
"node_modules/undici-types": {
diff --git a/package.json b/package.json
index f36fb27..897db95 100644
--- a/package.json
+++ b/package.json
@@ -55,7 +55,6 @@
"optionalDependencies": {
"@rollup/rollup-linux-x64-gnu": "4.9.5",
"@tailwindcss/oxide-linux-x64-gnu": "^4.0.1",
- "lightningcss-linux-x64-gnu": "^1.29.1",
- "node-mac-permissions": "^2.5.0"
+ "lightningcss-linux-x64-gnu": "^1.29.1"
}
}
diff --git a/resources/js/components/AudioPlayer.vue b/resources/js/components/AudioPlayer.vue
new file mode 100644
index 0000000..4d0d969
--- /dev/null
+++ b/resources/js/components/AudioPlayer.vue
@@ -0,0 +1,366 @@
+
+ Conversation Recording
+
+ Left channel: Salesperson | Right channel: Customer +
+No transcript available
+ Record conversations locally with separate channels +
+• Left channel: Salesperson (you)
+• Right channel: Customer/Speaker
+
+ {{ recordingPath }}
+
+
+ + How often to save recording progress to disk +
+ +Privacy Notice
+All recordings are stored locally on your device. They are never uploaded to any server. Please ensure you comply with local laws and obtain necessary consent before recording conversations.
+