fraim-hub 2.0.258 → 2.0.261

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fraim-hub",
3
- "version": "2.0.258",
3
+ "version": "2.0.261",
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.258",
166
+ "fraim": "2.0.261",
167
167
  "mongodb": "^7.0.0",
168
168
  "node-cron": "4.2.1",
169
169
  "node-edge-tts": "^1.2.10",
@@ -656,11 +656,12 @@ function taskPaneProjectEntries() {
656
656
  return Array.from(byPath.values());
657
657
  }
658
658
 
659
- function taskPaneJobEntries() {
660
- const jobs = [
661
- ...((state.bootstrap && state.bootstrap.jobs) || []),
662
- ...((state.bootstrap && state.bootstrap.managerTemplates) || []),
663
- ];
659
+ function taskPaneJobEntries() {
660
+ const jobs = [
661
+ { id: '__freeform__', title: 'Ad-hoc instructions', intent: 'Start from the instructions below.' },
662
+ ...((state.bootstrap && state.bootstrap.jobs) || []),
663
+ ...((state.bootstrap && state.bootstrap.managerTemplates) || []),
664
+ ];
664
665
  const seen = new Set();
665
666
  return jobs
666
667
  .filter((job) => job && job.id && !PAGE_SCOPED_JOBS.has(job.id))
@@ -714,7 +715,7 @@ function ensureTaskPaneLauncher() {
714
715
  const fields = [
715
716
  ['Project', 'task-pane-project-select', 'select'],
716
717
  ['Agent tool', 'task-pane-employee-select', 'select'],
717
- ['Job', 'task-pane-job-select', 'select'],
718
+ ['Job', 'task-pane-job-select', 'select'],
718
719
  ['Instructions', 'task-pane-instructions', 'textarea'],
719
720
  ];
720
721
  fields.forEach(([labelText, id, tag]) => {
@@ -725,11 +726,11 @@ function ensureTaskPaneLauncher() {
725
726
  span.textContent = labelText;
726
727
  const input = document.createElement(tag);
727
728
  input.id = id;
728
- if (tag === 'textarea') {
729
- input.rows = 4;
730
- input.placeholder = 'Add the outcome you want from this Word context.';
731
- input.addEventListener('input', () => { input.dataset.userTouched = '1'; });
732
- }
729
+ if (tag === 'textarea') {
730
+ input.rows = 4;
731
+ input.placeholder = 'Tell the employee what to do with this Office context.';
732
+ input.addEventListener('input', () => { input.dataset.userTouched = '1'; });
733
+ }
733
734
  label.appendChild(span);
734
735
  label.appendChild(input);
735
736
  root.appendChild(label);
@@ -779,14 +780,15 @@ function renderTaskPaneLauncher() {
779
780
  const employeeSelect = document.getElementById('task-pane-employee-select');
780
781
  const jobSelect = document.getElementById('task-pane-job-select');
781
782
  const instructions = document.getElementById('task-pane-instructions');
782
- const start = document.getElementById('task-pane-start-job');
783
- const current = document.getElementById('task-pane-current-job');
784
- const context = document.getElementById('task-pane-context-summary');
785
- const conv = typeof activeConversation === 'function' ? activeConversation() : null;
786
-
787
- taskPaneSetOptions(projectSelect, projects, (project) => project.folderPath, (project) => project.name || friendlyProjectShortName(project.folderPath), state.projectPath);
788
- taskPaneSetOptions(employeeSelect, agents, (agent) => agent.id, (agent) => agent.label || agent.id, state.selectedEmployeeId);
789
- taskPaneSetOptions(jobSelect, jobs, (job) => job.id, (job) => job.title || job.id, null);
783
+ const start = document.getElementById('task-pane-start-job');
784
+ const current = document.getElementById('task-pane-current-job');
785
+ const context = document.getElementById('task-pane-context-summary');
786
+ const conv = typeof activeConversation === 'function' ? activeConversation() : null;
787
+ const priorJobId = jobSelect && jobSelect.value;
788
+
789
+ taskPaneSetOptions(projectSelect, projects, (project) => project.folderPath, (project) => project.name || friendlyProjectShortName(project.folderPath), state.projectPath);
790
+ taskPaneSetOptions(employeeSelect, agents, (agent) => agent.id, (agent) => agent.label || agent.id, state.selectedEmployeeId);
791
+ taskPaneSetOptions(jobSelect, jobs, (job) => job.id, (job) => job.title || job.id, priorJobId || '__freeform__');
790
792
 
791
793
  if (instructions && instructions.dataset.userTouched !== '1') {
792
794
  instructions.value = taskPaneInstructionSeed();
@@ -832,16 +834,19 @@ async function taskPaneStartSelectedJob() {
832
834
  const jobSelect = document.getElementById('task-pane-job-select');
833
835
  const instructions = document.getElementById('task-pane-instructions');
834
836
  const start = document.getElementById('task-pane-start-job');
835
- const statusEl = document.getElementById('task-pane-start-status');
836
- const selectedProject = projectSelect && projectSelect.value;
837
- const requestedEmployeeId = employeeSelect && employeeSelect.value;
838
- if (selectedProject && tfCanonicalProjectPath(selectedProject) !== tfCanonicalProjectPath(state.projectPath)) {
839
- await taskPaneSwitchProject(selectedProject);
840
- const updatedEmployeeSelect = document.getElementById('task-pane-employee-select');
841
- if (updatedEmployeeSelect && requestedEmployeeId) updatedEmployeeSelect.value = requestedEmployeeId;
842
- }
843
- const jobs = taskPaneJobEntries();
844
- const job = jobs.find((entry) => entry.id === (jobSelect && jobSelect.value));
837
+ const statusEl = document.getElementById('task-pane-start-status');
838
+ const selectedProject = projectSelect && projectSelect.value;
839
+ const requestedEmployeeId = employeeSelect && employeeSelect.value;
840
+ const requestedJobId = jobSelect && jobSelect.value;
841
+ if (selectedProject && tfCanonicalProjectPath(selectedProject) !== tfCanonicalProjectPath(state.projectPath)) {
842
+ await taskPaneSwitchProject(selectedProject);
843
+ const updatedEmployeeSelect = document.getElementById('task-pane-employee-select');
844
+ if (updatedEmployeeSelect && requestedEmployeeId) updatedEmployeeSelect.value = requestedEmployeeId;
845
+ const updatedJobSelect = document.getElementById('task-pane-job-select');
846
+ if (updatedJobSelect && requestedJobId) updatedJobSelect.value = requestedJobId;
847
+ }
848
+ const jobs = taskPaneJobEntries();
849
+ const job = jobs.find((entry) => entry.id === requestedJobId);
845
850
  const employeeId = requestedEmployeeId || (employeeSelect && employeeSelect.value);
846
851
  if (!job || !employeeId) return;
847
852
  if (start) start.disabled = true;
@@ -2866,24 +2866,27 @@ 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
- }
2869
+ body:is([data-surface="task-pane"],[data-surface="extension"]) {
2870
+ font-size: 13px;
2871
+ overflow: auto;
2872
+ background: var(--bg);
2873
+ color: var(--text);
2874
+ }
2873
2875
  body:is([data-surface="task-pane"],[data-surface="extension"]) .hub-tabs,
2874
2876
  body:is([data-surface="task-pane"],[data-surface="extension"]):not(.task-pane-run-active) .hub-area,
2875
2877
  body:is([data-surface="task-pane"],[data-surface="extension"]) .proj-tabs {
2876
2878
  display: none !important;
2877
2879
  }
2878
2880
  .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
- }
2881
+ body:is([data-surface="task-pane"],[data-surface="extension"]):not(.task-pane-run-active) .task-pane-launcher {
2882
+ display: flex;
2883
+ flex-direction: column;
2884
+ gap: 10px;
2885
+ padding: 12px;
2886
+ border-bottom: 1px solid var(--line, rgba(0,0,0,0.07));
2887
+ background: var(--surface, #fff);
2888
+ color: var(--text, #171717);
2889
+ }
2887
2890
  body:is([data-surface="task-pane"],[data-surface="extension"]).task-pane-run-active #area-projects {
2888
2891
  display: flex !important;
2889
2892
  min-height: 100vh;
@@ -2940,17 +2943,27 @@ body:is([data-surface="task-pane"],[data-surface="extension"]).task-pane-run-act
2940
2943
  font-weight: 600;
2941
2944
  color: var(--muted);
2942
2945
  }
2943
- .tp-launcher-field select,
2944
- .tp-launcher-field textarea {
2945
- width: 100%;
2946
- min-width: 0;
2947
- border: 1px solid var(--border, rgba(0,0,0,0.12));
2948
- border-radius: 8px;
2949
- background: var(--panel, #fff);
2950
- color: var(--text, #171717);
2951
- font: inherit;
2952
- font-size: 12px;
2953
- }
2946
+ .tp-launcher-field select,
2947
+ .tp-launcher-field textarea {
2948
+ width: 100%;
2949
+ min-width: 0;
2950
+ border: 1px solid var(--line, rgba(0,0,0,0.12));
2951
+ border-radius: 8px;
2952
+ background: var(--surface, #fff);
2953
+ color: var(--text, #171717);
2954
+ font: inherit;
2955
+ font-size: 12px;
2956
+ }
2957
+ .tp-launcher-field select:focus,
2958
+ .tp-launcher-field textarea:focus {
2959
+ outline: 2px solid var(--accent, #0071e3);
2960
+ outline-offset: 1px;
2961
+ border-color: var(--accent, #0071e3);
2962
+ }
2963
+ .tp-launcher-field textarea::placeholder {
2964
+ color: var(--muted);
2965
+ opacity: 1;
2966
+ }
2954
2967
  .tp-launcher-field select {
2955
2968
  height: 34px;
2956
2969
  padding: 0 8px;
@@ -2987,8 +3000,9 @@ body:is([data-surface="task-pane"],[data-surface="extension"]).task-pane-run-act
2987
3000
  gap: 10px;
2988
3001
  min-width: 0;
2989
3002
  padding: 10px 12px;
2990
- border-bottom: 1px solid var(--border, rgba(0,0,0,0.07));
3003
+ border-bottom: 1px solid var(--line, rgba(0,0,0,0.07));
2991
3004
  background: var(--surface, #fff);
3005
+ color: var(--text, #171717);
2992
3006
  }
2993
3007
  .tp-run-copy {
2994
3008
  min-width: 0;
@@ -3022,6 +3036,31 @@ body:is([data-surface="task-pane"],[data-surface="extension"]) #task-pane-new-jo
3022
3036
  font-size: 12px;
3023
3037
  white-space: nowrap;
3024
3038
  }
3039
+ :root[data-theme="dark"] body:is([data-surface="task-pane"],[data-surface="extension"]) {
3040
+ background: var(--bg);
3041
+ }
3042
+ :root[data-theme="dark"] body:is([data-surface="task-pane"],[data-surface="extension"]):not(.task-pane-run-active) .task-pane-launcher,
3043
+ :root[data-theme="dark"] body:is([data-surface="task-pane"],[data-surface="extension"]).task-pane-run-active .task-pane-run-nav {
3044
+ background: #242424;
3045
+ border-color: rgba(255, 255, 255, 0.16);
3046
+ }
3047
+ :root[data-theme="dark"] body:is([data-surface="task-pane"],[data-surface="extension"]) .tp-launcher-field select,
3048
+ :root[data-theme="dark"] body:is([data-surface="task-pane"],[data-surface="extension"]) .tp-launcher-field textarea {
3049
+ background: #171717;
3050
+ color: #f2f2f2;
3051
+ border-color: rgba(255, 255, 255, 0.22);
3052
+ }
3053
+ :root[data-theme="dark"] body:is([data-surface="task-pane"],[data-surface="extension"]) .tp-launcher-field select option {
3054
+ background: #171717;
3055
+ color: #f2f2f2;
3056
+ }
3057
+ :root[data-theme="dark"] body:is([data-surface="task-pane"],[data-surface="extension"]) .tp-launcher-context,
3058
+ :root[data-theme="dark"] body:is([data-surface="task-pane"],[data-surface="extension"]) .tp-launcher-status,
3059
+ :root[data-theme="dark"] body:is([data-surface="task-pane"],[data-surface="extension"]) .tp-launcher-field,
3060
+ :root[data-theme="dark"] body:is([data-surface="task-pane"],[data-surface="extension"]) .tp-run-eyebrow,
3061
+ :root[data-theme="dark"] body:is([data-surface="task-pane"],[data-surface="extension"]) .tp-run-meta {
3062
+ color: #c7c7c7;
3063
+ }
3025
3064
  body:is([data-surface="task-pane"],[data-surface="extension"]) .page {
3026
3065
  padding: 10px 12px 8px;
3027
3066
  gap: 10px;