fraim-hub 2.0.251 → 2.0.253
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.
|
@@ -99,17 +99,21 @@ function configureAutoUpdater() {
|
|
|
99
99
|
// ---------------------------------------------------------------------------
|
|
100
100
|
// Word manifest sideload (runs once on first launch)
|
|
101
101
|
// ---------------------------------------------------------------------------
|
|
102
|
-
function ensureWordSideload(projectPath,
|
|
102
|
+
function ensureWordSideload(projectPath, httpsPort) {
|
|
103
103
|
// Flag version bump: bump this string when new manifests are added so all
|
|
104
104
|
// users get re-sideloaded on their next launch.
|
|
105
|
-
const FLAG_VERSION = '
|
|
106
|
-
const expectedFlag = `${FLAG_VERSION}:${
|
|
105
|
+
const FLAG_VERSION = 'v5-https-port';
|
|
106
|
+
const expectedFlag = `${FLAG_VERSION}:${httpsPort}`;
|
|
107
107
|
const flagPath = path_1.default.join(electron_1.app.getPath('userData'), 'word-sideloaded.flag');
|
|
108
108
|
const existingFlag = fs_1.default.existsSync(flagPath) ? fs_1.default.readFileSync(flagPath, 'utf8') : null;
|
|
109
109
|
if ((0, office_sideload_1.shouldSkipSideloadForFlag)(existingFlag, expectedFlag, (0, office_sideload_1.isSideloaded)()))
|
|
110
110
|
return;
|
|
111
|
-
if (
|
|
112
|
-
const result = (0, office_sideload_1.sideloadManifest)(projectPath, {
|
|
111
|
+
if (httpsPort > 0) {
|
|
112
|
+
const result = (0, office_sideload_1.sideloadManifest)(projectPath, {
|
|
113
|
+
webPort: httpsPort,
|
|
114
|
+
webProtocol: 'https',
|
|
115
|
+
userDataDir: electron_1.app.getPath('userData'),
|
|
116
|
+
});
|
|
113
117
|
if (!result.ok) {
|
|
114
118
|
console.warn('[fraim] Office sideload skipped:', result.reason);
|
|
115
119
|
return; // don't write flag — retry next launch
|
|
@@ -362,7 +366,7 @@ async function launchDesktopShell(options) {
|
|
|
362
366
|
catch (err) {
|
|
363
367
|
console.warn('[fraim] could not write hub runtime file:', err);
|
|
364
368
|
}
|
|
365
|
-
ensureWordSideload(resolvedProjectPath,
|
|
369
|
+
ensureWordSideload(resolvedProjectPath, httpsPort);
|
|
366
370
|
const hubUrl = `http://127.0.0.1:${httpPort}/ai-hub/`;
|
|
367
371
|
createTray(hubUrl, runtimeId);
|
|
368
372
|
await createWindow(hubUrl, runtimeId);
|
|
@@ -62,18 +62,20 @@ function macWefPath(container, guid) {
|
|
|
62
62
|
function generatedManifestPath(entry, userDataDir) {
|
|
63
63
|
return path_1.default.join(userDataDir, 'office-manifests', entry.guid, 'manifest.xml');
|
|
64
64
|
}
|
|
65
|
-
function manifestXmlForPort(xml,
|
|
66
|
-
return xml.replace(/https?:\/\/(?:localhost|127\.0\.0\.1):(43091|43092)/g,
|
|
65
|
+
function manifestXmlForPort(xml, webPort, protocol = 'https') {
|
|
66
|
+
return xml.replace(/https?:\/\/(?:localhost|127\.0\.0\.1):(43091|43092)/g, `${protocol}://127.0.0.1:${webPort}`);
|
|
67
67
|
}
|
|
68
68
|
function shouldSkipSideloadForFlag(existingFlag, expectedFlag, sideloaded) {
|
|
69
69
|
return existingFlag?.trim() === expectedFlag && sideloaded;
|
|
70
70
|
}
|
|
71
71
|
function prepareManifestForSideload(entry, sourcePath, options) {
|
|
72
|
-
|
|
72
|
+
const webPort = options.webPort ?? options.httpPort;
|
|
73
|
+
if (!webPort)
|
|
73
74
|
return sourcePath;
|
|
75
|
+
const webProtocol = options.webProtocol ?? 'https';
|
|
74
76
|
const userDataDir = options.userDataDir || path_1.default.join(os_1.default.homedir(), '.fraim');
|
|
75
77
|
const dest = generatedManifestPath(entry, userDataDir);
|
|
76
|
-
const rendered = manifestXmlForPort(fs_1.default.readFileSync(sourcePath, 'utf8'),
|
|
78
|
+
const rendered = manifestXmlForPort(fs_1.default.readFileSync(sourcePath, 'utf8'), webPort, webProtocol);
|
|
77
79
|
fs_1.default.mkdirSync(path_1.default.dirname(dest), { recursive: true });
|
|
78
80
|
fs_1.default.writeFileSync(dest, rendered, { encoding: 'utf8' });
|
|
79
81
|
return dest;
|
|
@@ -120,6 +122,7 @@ function winWriteRegisteredValue(guid, manifestPath) {
|
|
|
120
122
|
// Remove the older root-value registration if present. Office does not need
|
|
121
123
|
// it, and keeping two registration shapes makes stale-state diagnosis harder.
|
|
122
124
|
(0, child_process_1.spawnSync)('reg', ['delete', WEF_DEVELOPER_KEY, '/v', guid, '/f'], { encoding: 'utf8' });
|
|
125
|
+
(0, child_process_1.spawnSync)('reg', ['delete', `${WEF_DEVELOPER_KEY}\\${guid}`, '/f'], { encoding: 'utf8' });
|
|
123
126
|
return { ok: true };
|
|
124
127
|
}
|
|
125
128
|
// ---------------------------------------------------------------------------
|
|
@@ -178,6 +181,7 @@ function removeSideload() {
|
|
|
178
181
|
for (const entry of MANIFESTS) {
|
|
179
182
|
if (process.platform === 'win32') {
|
|
180
183
|
(0, child_process_1.spawnSync)('reg', ['delete', WEF_DEVELOPER_KEY, '/v', entry.guid, '/f'], { encoding: 'utf8' });
|
|
184
|
+
(0, child_process_1.spawnSync)('reg', ['delete', `${WEF_DEVELOPER_KEY}\\${entry.guid}`, '/f'], { encoding: 'utf8' });
|
|
181
185
|
(0, child_process_1.spawnSync)('reg', ['delete', winDeveloperManifestSubkey(entry.guid), '/f'], { encoding: 'utf8' });
|
|
182
186
|
}
|
|
183
187
|
else if (process.platform === 'darwin') {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
xmlns:bt="http://schemas.microsoft.com/office/officeappbasictypes/1.0"
|
|
5
5
|
xsi:type="TaskPaneApp">
|
|
6
6
|
<Id>d1090951-50cf-4cf2-9d12-b0f8541d265c</Id>
|
|
7
|
-
<Version>1.0.
|
|
7
|
+
<Version>1.0.1.0</Version>
|
|
8
8
|
<ProviderName>FRAIM</ProviderName>
|
|
9
9
|
<DefaultLocale>en-US</DefaultLocale>
|
|
10
10
|
<DisplayName DefaultValue="FRAIM"/>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fraim-hub",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.253",
|
|
4
4
|
"description": "FRAIM Hub local companion package.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"fraim-hub": "bin/fraim-hub.js",
|
|
@@ -163,7 +163,7 @@
|
|
|
163
163
|
"electron": "^41.2.2",
|
|
164
164
|
"electron-updater": "^6.8.9",
|
|
165
165
|
"express": "^5.2.1",
|
|
166
|
-
"fraim": "2.0.
|
|
166
|
+
"fraim": "2.0.253",
|
|
167
167
|
"mongodb": "^7.0.0",
|
|
168
168
|
"node-cron": "4.2.1",
|
|
169
169
|
"node-edge-tts": "^1.2.10",
|
package/public/ai-hub/index.html
CHANGED
|
@@ -500,7 +500,7 @@
|
|
|
500
500
|
</div>
|
|
501
501
|
</div>
|
|
502
502
|
<div class="coach-input">
|
|
503
|
-
<textarea id="coach-text" placeholder="Tell the employee what to do next..."></textarea>
|
|
503
|
+
<textarea id="coach-text" aria-label="Coach the employee" placeholder="Tell the employee what to do next..."></textarea>
|
|
504
504
|
<button class="send-button" type="button" id="send" disabled>↑</button>
|
|
505
505
|
</div>
|
|
506
506
|
<div class="coach-note" id="coach-note"></div>
|
package/public/ai-hub/script.js
CHANGED
|
@@ -529,12 +529,40 @@ function renderWordContextInModal() {
|
|
|
529
529
|
body.textContent = buildWordContextBlock(wc);
|
|
530
530
|
}
|
|
531
531
|
|
|
532
|
-
function isTaskPaneSurface() {
|
|
533
|
-
return document.body.dataset.surface === 'task-pane' || document.body.dataset.surface === 'extension';
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
function
|
|
537
|
-
|
|
532
|
+
function isTaskPaneSurface() {
|
|
533
|
+
return document.body.dataset.surface === 'task-pane' || document.body.dataset.surface === 'extension';
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
function syncTaskPaneSurfaceMode() {
|
|
537
|
+
if (!isTaskPaneSurface()) return;
|
|
538
|
+
const conv = typeof activeConversation === 'function' ? activeConversation() : null;
|
|
539
|
+
const hasActiveConversation = !!conv;
|
|
540
|
+
document.body.classList.toggle('task-pane-run-active', hasActiveConversation);
|
|
541
|
+
if (!hasActiveConversation || typeof tf === 'undefined' || typeof tfSelectProjectView !== 'function') return;
|
|
542
|
+
const projectPath = (conv && conv.projectPath) || state.projectPath;
|
|
543
|
+
let project = typeof tfProjectForPath === 'function' ? tfProjectForPath(projectPath) : null;
|
|
544
|
+
if (!project && projectPath && typeof tfNormalizeProject === 'function' && typeof tfApplyUniqueProjectIds === 'function') {
|
|
545
|
+
tf.projects = tfApplyUniqueProjectIds([...(tf.projects || []), tfNormalizeProject({
|
|
546
|
+
name: friendlyProjectShortName(projectPath),
|
|
547
|
+
folderPath: projectPath,
|
|
548
|
+
}, projectPath)]);
|
|
549
|
+
project = typeof tfProjectForPath === 'function' ? tfProjectForPath(projectPath) : null;
|
|
550
|
+
}
|
|
551
|
+
const projectId = (project && project.id) || tf.activeProjectId;
|
|
552
|
+
if (!projectId) return;
|
|
553
|
+
if (tf.projectView === 'workspace' && tf.activeProjectId === projectId) {
|
|
554
|
+
const overview = document.getElementById('proj-overview');
|
|
555
|
+
const workspace = document.getElementById('proj-workspace');
|
|
556
|
+
if (overview) overview.hidden = true;
|
|
557
|
+
if (workspace) workspace.hidden = false;
|
|
558
|
+
return;
|
|
559
|
+
}
|
|
560
|
+
tfSelectProjectView('workspace', projectId).catch((error) =>
|
|
561
|
+
console.warn('[ai-hub] could not show task-pane run workspace:', error));
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
function taskPaneProjectEntries() {
|
|
565
|
+
const byPath = new Map();
|
|
538
566
|
const add = (project) => {
|
|
539
567
|
if (!project) return;
|
|
540
568
|
const folderPath = project.folderPath || project.path || project.folder || '';
|
|
@@ -654,10 +682,11 @@ function ensureTaskPaneLauncher() {
|
|
|
654
682
|
return root;
|
|
655
683
|
}
|
|
656
684
|
|
|
657
|
-
function renderTaskPaneLauncher() {
|
|
658
|
-
if (!isTaskPaneSurface() || !state.bootstrap) return;
|
|
659
|
-
|
|
660
|
-
|
|
685
|
+
function renderTaskPaneLauncher() {
|
|
686
|
+
if (!isTaskPaneSurface() || !state.bootstrap) return;
|
|
687
|
+
syncTaskPaneSurfaceMode();
|
|
688
|
+
ensureTaskPaneLauncher();
|
|
689
|
+
const projects = taskPaneProjectEntries();
|
|
661
690
|
const jobs = taskPaneJobEntries();
|
|
662
691
|
const agents = hubConfiguredAgents().filter((agent) => agent.available !== false && agent.enabled !== false);
|
|
663
692
|
const projectSelect = document.getElementById('task-pane-project-select');
|
|
@@ -3152,9 +3181,10 @@ function handleConversationFocusEscape(e) {
|
|
|
3152
3181
|
closeConversationFocus();
|
|
3153
3182
|
}
|
|
3154
3183
|
|
|
3155
|
-
function renderActive() {
|
|
3156
|
-
const conv = activeConversation();
|
|
3157
|
-
if (typeof
|
|
3184
|
+
function renderActive() {
|
|
3185
|
+
const conv = activeConversation();
|
|
3186
|
+
if (typeof syncTaskPaneSurfaceMode === 'function') syncTaskPaneSurfaceMode();
|
|
3187
|
+
if (typeof tfApplyWorkspaceMode === 'function') tfApplyWorkspaceMode();
|
|
3158
3188
|
if (!conv) {
|
|
3159
3189
|
closeConversationFocus();
|
|
3160
3190
|
els['empty'].hidden = false;
|
package/public/ai-hub/styles.css
CHANGED
|
@@ -2866,24 +2866,52 @@ button.small { padding: 4px 10px; font-size: 12px; }
|
|
|
2866
2866
|
body:is([data-surface="task-pane"],[data-surface="extension"]). No media queries — this is a surface
|
|
2867
2867
|
flag, not a viewport breakpoint. */
|
|
2868
2868
|
|
|
2869
|
-
body:is([data-surface="task-pane"],[data-surface="extension"]) {
|
|
2870
|
-
font-size: 13px;
|
|
2871
|
-
overflow: auto;
|
|
2872
|
-
}
|
|
2873
|
-
body:is([data-surface="task-pane"],[data-surface="extension"]) .hub-tabs,
|
|
2874
|
-
body:is([data-surface="task-pane"],[data-surface="extension"]) .hub-area,
|
|
2875
|
-
body:is([data-surface="task-pane"],[data-surface="extension"]) .proj-tabs {
|
|
2876
|
-
display: none !important;
|
|
2877
|
-
}
|
|
2878
|
-
.task-pane-launcher { display: none; }
|
|
2879
|
-
body:is([data-surface="task-pane"],[data-surface="extension"]) .task-pane-launcher {
|
|
2880
|
-
display: flex;
|
|
2881
|
-
flex-direction: column;
|
|
2882
|
-
gap: 10px;
|
|
2883
|
-
padding: 12px;
|
|
2884
|
-
border-bottom: 1px solid var(--border, rgba(0,0,0,0.07));
|
|
2885
|
-
background: var(--surface, #fff);
|
|
2886
|
-
}
|
|
2869
|
+
body:is([data-surface="task-pane"],[data-surface="extension"]) {
|
|
2870
|
+
font-size: 13px;
|
|
2871
|
+
overflow: auto;
|
|
2872
|
+
}
|
|
2873
|
+
body:is([data-surface="task-pane"],[data-surface="extension"]) .hub-tabs,
|
|
2874
|
+
body:is([data-surface="task-pane"],[data-surface="extension"]):not(.task-pane-run-active) .hub-area,
|
|
2875
|
+
body:is([data-surface="task-pane"],[data-surface="extension"]) .proj-tabs {
|
|
2876
|
+
display: none !important;
|
|
2877
|
+
}
|
|
2878
|
+
.task-pane-launcher { display: none; }
|
|
2879
|
+
body:is([data-surface="task-pane"],[data-surface="extension"]):not(.task-pane-run-active) .task-pane-launcher {
|
|
2880
|
+
display: flex;
|
|
2881
|
+
flex-direction: column;
|
|
2882
|
+
gap: 10px;
|
|
2883
|
+
padding: 12px;
|
|
2884
|
+
border-bottom: 1px solid var(--border, rgba(0,0,0,0.07));
|
|
2885
|
+
background: var(--surface, #fff);
|
|
2886
|
+
}
|
|
2887
|
+
body:is([data-surface="task-pane"],[data-surface="extension"]).task-pane-run-active #area-projects {
|
|
2888
|
+
display: flex !important;
|
|
2889
|
+
min-height: 100vh;
|
|
2890
|
+
}
|
|
2891
|
+
body:is([data-surface="task-pane"],[data-surface="extension"]).task-pane-run-active #proj-workspace {
|
|
2892
|
+
display: flex;
|
|
2893
|
+
flex: 1 1 auto;
|
|
2894
|
+
min-width: 0;
|
|
2895
|
+
overflow: visible;
|
|
2896
|
+
}
|
|
2897
|
+
body:is([data-surface="task-pane"],[data-surface="extension"]).task-pane-run-active .tree-sidebar,
|
|
2898
|
+
body:is([data-surface="task-pane"],[data-surface="extension"]).task-pane-run-active .tree-collapse-btn,
|
|
2899
|
+
body:is([data-surface="task-pane"],[data-surface="extension"]).task-pane-run-active .tree-resizer {
|
|
2900
|
+
display: none !important;
|
|
2901
|
+
}
|
|
2902
|
+
body:is([data-surface="task-pane"],[data-surface="extension"]).task-pane-run-active .workspace-conv {
|
|
2903
|
+
width: 100%;
|
|
2904
|
+
min-width: 0;
|
|
2905
|
+
}
|
|
2906
|
+
body:is([data-surface="task-pane"],[data-surface="extension"]).task-pane-run-active .workspace-conv .layout {
|
|
2907
|
+
display: flex;
|
|
2908
|
+
flex-direction: column;
|
|
2909
|
+
min-width: 0;
|
|
2910
|
+
overflow: visible;
|
|
2911
|
+
}
|
|
2912
|
+
body:is([data-surface="task-pane"],[data-surface="extension"]).task-pane-run-active .word-context-bar {
|
|
2913
|
+
flex: 0 0 auto;
|
|
2914
|
+
}
|
|
2887
2915
|
.tp-launcher-header {
|
|
2888
2916
|
display: flex;
|
|
2889
2917
|
flex-direction: column;
|