clementine-agent 1.18.89 → 1.18.90

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.
@@ -20217,7 +20217,10 @@ if('serviceWorker' in navigator){navigator.serviceWorker.getRegistrations().then
20217
20217
  <h4>What it does</h4>
20218
20218
  <p class="cron-section-desc">The instruction the agent receives. Long prompts are fine — drag the corner to resize.</p>
20219
20219
  <div class="form-group">
20220
- <label class="form-label">Prompt</label>
20220
+ <label class="form-label" style="display:flex;align-items:center;gap:8px">
20221
+ Prompt
20222
+ <a href="#" id="cron-prompt-history-link" onclick="event.preventDefault();openPromptHistory()" style="display:none;font-size:11px;font-weight:normal;color:var(--text-muted);text-decoration:none;border-bottom:1px dotted var(--border)">View prompt history</a>
20223
+ </label>
20221
20224
  <textarea id="cron-prompt" class="cron-prompt-textarea" placeholder="What should the AI do when this task runs?"></textarea>
20222
20225
  <div class="form-hint">The instruction sent to the AI agent when this task fires.</div>
20223
20226
  </div>
@@ -20450,6 +20453,29 @@ if('serviceWorker' in navigator){navigator.serviceWorker.getRegistrations().then
20450
20453
 
20451
20454
  <!-- (legacy standalone Preview modal removed in 1.18.70 — preview now lives as a tab inside the cron modal) -->
20452
20455
 
20456
+ <!-- ═══ Prompt History Modal — PRD §11 / 1.18.90 ═══
20457
+ Lists every past prompt revision for the currently-edited task.
20458
+ Each row shows ts + changedBy + a preview, expandable to full
20459
+ content. "Restore" copies the old prompt back into the editor —
20460
+ it does NOT auto-save, so the user reviews + clicks Save Changes
20461
+ to commit. The current draft in the editor is preserved if the
20462
+ user closes without restoring. -->
20463
+ <div class="modal-overlay" id="prompt-history-modal">
20464
+ <div class="modal" style="max-width:720px;width:96vw;max-height:88vh;display:flex;flex-direction:column">
20465
+ <div class="modal-header">
20466
+ <h3>Prompt history</h3>
20467
+ <button class="btn-ghost btn-sm" onclick="closePromptHistory()">&times;</button>
20468
+ </div>
20469
+ <div class="modal-body" style="padding:0;flex:1;min-height:0;overflow-y:auto">
20470
+ <div id="prompt-history-list" style="padding:18px"></div>
20471
+ </div>
20472
+ <div class="modal-footer">
20473
+ <span style="flex:1;font-size:11px;color:var(--text-muted)">Restore copies a version into the editor. You still need to click <strong>Save Changes</strong> to commit it.</span>
20474
+ <button onclick="closePromptHistory()">Close</button>
20475
+ </div>
20476
+ </div>
20477
+ </div>
20478
+
20453
20479
  <!-- ═══ MCP Server Edit Modal — PRD Phase 2.1 ═══ -->
20454
20480
  <div class="modal-overlay" id="mcp-edit-modal">
20455
20481
  <div class="modal" style="max-width:640px;width:96vw">
@@ -25965,6 +25991,87 @@ async function loadCronPreviewIntoTab(jobName) {
25965
25991
  // Mark the preview as stale (call after save so next tab visit refetches).
25966
25992
  function markCronPreviewDirty() { _cronPreviewLoadedFor = null; }
25967
25993
 
25994
+ // ── PRD §11 / 1.18.90: Prompt history viewer ────────────────────────
25995
+ // Reads /api/cron/:job/prompt-history (already populated on every PUT
25996
+ // since 1.18.x). Each version is the OLD prompt at the moment of a save,
25997
+ // so rolling back means picking the version that was AFTER the change
25998
+ // you want to undo (or the current saved value if you want the most
25999
+ // recent committed state).
26000
+ async function openPromptHistory() {
26001
+ if (!editingCronJob) {
26002
+ toast('Save the task first, then prompt history will be available.', 'info');
26003
+ return;
26004
+ }
26005
+ var modal = document.getElementById('prompt-history-modal');
26006
+ var list = document.getElementById('prompt-history-list');
26007
+ if (!modal || !list) return;
26008
+ list.innerHTML = '<div style="padding:24px;color:var(--text-muted);text-align:center">Loading prompt history…</div>';
26009
+ modal.classList.add('show');
26010
+ try {
26011
+ var r = await apiFetch('/api/cron/' + encodeURIComponent(editingCronJob) + '/prompt-history');
26012
+ var d = await r.json();
26013
+ var versions = (d && d.versions) || [];
26014
+ if (versions.length === 0) {
26015
+ list.innerHTML = '<div style="padding:36px 24px;color:var(--text-muted);text-align:center;line-height:1.6">'
26016
+ + '<div style="font-weight:500;color:var(--text-secondary);margin-bottom:8px">No prior prompt versions yet</div>'
26017
+ + '<div style="font-size:12px">A version is recorded each time you save a different prompt. The first edit you make to this task will create version 1.</div>'
26018
+ + '</div>';
26019
+ return;
26020
+ }
26021
+ var html = '<div style="font-size:11px;color:var(--text-muted);margin-bottom:12px">Newest first. Each entry is the prompt as it was BEFORE that save — restoring rolls the editor back to the version that was active before that change landed.</div>';
26022
+ for (var i = 0; i < versions.length; i++) {
26023
+ var v = versions[i];
26024
+ var ts = v.timestamp ? new Date(v.timestamp).toLocaleString() : 'unknown time';
26025
+ var who = v.changedBy || 'dashboard';
26026
+ var prompt = String(v.prompt || '');
26027
+ var preview = prompt.slice(0, 200).replace(/\\s+/g, ' ');
26028
+ var rowId = 'pmt-hist-' + i;
26029
+ var promptB64 = btoa(unescape(encodeURIComponent(prompt))); // safe transport for restore
26030
+ html += '<div style="background:var(--bg-secondary);border:1px solid var(--border);border-radius:8px;padding:14px;margin-bottom:10px">';
26031
+ html += '<div style="display:flex;align-items:center;gap:10px;margin-bottom:8px">';
26032
+ html += '<span style="font-size:11px;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:0.04em">v' + esc(v.version || (versions.length - i)) + '</span>';
26033
+ html += '<span style="font-size:12px;color:var(--text-primary)">' + esc(ts) + '</span>';
26034
+ html += '<span style="font-size:11px;color:var(--text-muted)">· by ' + esc(who) + '</span>';
26035
+ html += '<span style="flex:1"></span>';
26036
+ html += '<button class="btn-sm" onclick="document.getElementById(\\x27' + rowId + '\\x27).style.display=document.getElementById(\\x27' + rowId + '\\x27).style.display===\\x27none\\x27?\\x27block\\x27:\\x27none\\x27" style="font-size:11px;padding:3px 8px">Show full</button>';
26037
+ html += '<button class="btn-sm btn-primary" onclick="restorePromptVersion(\\x27' + promptB64 + '\\x27)" style="font-size:11px;padding:3px 10px">Restore</button>';
26038
+ html += '</div>';
26039
+ html += '<div style="font-size:12px;color:var(--text-secondary);line-height:1.5;font-family:\\x27JetBrains Mono\\x27,monospace">' + esc(preview) + (prompt.length > 200 ? '…' : '') + '</div>';
26040
+ html += '<pre id="' + rowId + '" style="display:none;margin-top:10px;font-size:11px;font-family:\\x27JetBrains Mono\\x27,monospace;background:var(--bg-tertiary);border:1px solid var(--border);padding:10px;border-radius:6px;white-space:pre-wrap;word-break:break-word;max-height:280px;overflow-y:auto">' + esc(prompt) + '</pre>';
26041
+ html += '</div>';
26042
+ }
26043
+ list.innerHTML = html;
26044
+ } catch (e) {
26045
+ list.innerHTML = '<div style="padding:24px;color:var(--red)">Failed to load history: ' + esc(String(e)) + '</div>';
26046
+ }
26047
+ }
26048
+
26049
+ function closePromptHistory() {
26050
+ var modal = document.getElementById('prompt-history-modal');
26051
+ if (modal) modal.classList.remove('show');
26052
+ }
26053
+
26054
+ // Restore copies the old prompt back into the editor's textarea. Doesn't
26055
+ // auto-save — the user must click Save Changes to commit, which keeps the
26056
+ // dirty-guard semantics intact and gives them a chance to back out.
26057
+ function restorePromptVersion(promptB64) {
26058
+ try {
26059
+ var prompt = decodeURIComponent(escape(atob(promptB64)));
26060
+ var ta = document.getElementById('cron-prompt');
26061
+ if (!ta) return;
26062
+ if (ta.value !== prompt && ta.value.trim() && !confirm('Replace the current prompt with this restored version? Your unsaved edits will be discarded.')) {
26063
+ return;
26064
+ }
26065
+ ta.value = prompt;
26066
+ // Switch to the Prompt tab so the user sees what just changed.
26067
+ if (typeof switchCronConfigTab === 'function') switchCronConfigTab('prompt');
26068
+ closePromptHistory();
26069
+ toast('Prompt restored. Click Save Changes to commit it.', 'info');
26070
+ } catch (e) {
26071
+ toast('Failed to restore: ' + String(e), 'error');
26072
+ }
26073
+ }
26074
+
25968
26075
  // PRD Phase 1.3a: inner Configure pane tabs. Sets the data-active-config-tab
25969
26076
  // attribute on #cron-tab-configure; CSS handles section visibility via
25970
26077
  // data-config-tab attributes on each section. JS-light by design.
@@ -26260,6 +26367,9 @@ function openCreateCronModal(agentSlug) {
26260
26367
  if (lastRunBtn) lastRunBtn.setAttribute('disabled', 'disabled');
26261
26368
  var runOnceBtn = document.getElementById('cron-run-once-btn');
26262
26369
  if (runOnceBtn) runOnceBtn.style.display = 'none';
26370
+ // PRD §11 / 1.18.90: prompt history link only meaningful for existing tasks.
26371
+ var historyLinkNew = document.getElementById('cron-prompt-history-link');
26372
+ if (historyLinkNew) historyLinkNew.style.display = 'none';
26263
26373
  var host = document.getElementById('cron-legacy-banner-host');
26264
26374
  if (host) host.innerHTML = '';
26265
26375
  // Reset the "Use a cron expression" link in case it was hidden last time.
@@ -26360,6 +26470,9 @@ function openEditCronModal(jobName) {
26360
26470
  // Show "Run task once" only for saved tasks.
26361
26471
  var runOnceBtnEdit = document.getElementById('cron-run-once-btn');
26362
26472
  if (runOnceBtnEdit) runOnceBtnEdit.style.display = '';
26473
+ // 1.18.90: surface prompt history link for saved tasks.
26474
+ var historyLinkEdit = document.getElementById('cron-prompt-history-link');
26475
+ if (historyLinkEdit) historyLinkEdit.style.display = '';
26363
26476
  // Render the most recent run from the loaded job into the Last run tab so
26364
26477
  // the user sees something the moment they switch to it (rather than a
26365
26478
  // dead empty pane). The pane updates live when Run task once fires.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clementine-agent",
3
- "version": "1.18.89",
3
+ "version": "1.18.90",
4
4
  "description": "Clementine — Personal AI Assistant (TypeScript)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",