zames_pro 2.37.1 → 2.39.0
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/dist/browser.js +28 -0
- package/dist/index.js +2 -6
- package/dist/scheduler.js +13 -0
- package/package.json +1 -1
package/dist/browser.js
CHANGED
|
@@ -499,6 +499,30 @@ export class DeepSeekBrowser {
|
|
|
499
499
|
catch { }
|
|
500
500
|
}
|
|
501
501
|
}
|
|
502
|
+
// A lightweight IN-PAGE marker so the operator, looking at the browser
|
|
503
|
+
// window, can tell that the agent is generating (the terminal spinner is not
|
|
504
|
+
// visible there). We prefix the tab title with a "⏳"; the ORIGINAL title is
|
|
505
|
+
// saved ONCE on the window and restored when generation ends, so DeepSeek's
|
|
506
|
+
// own chat title is never lost. Best-effort: a page error must never break
|
|
507
|
+
// the send loop.
|
|
508
|
+
async _setBusyTitle(busy) {
|
|
509
|
+
try {
|
|
510
|
+
await this.page.evaluate((on) => {
|
|
511
|
+
const w = window;
|
|
512
|
+
if (on) {
|
|
513
|
+
if (typeof w.__zamesTitle !== 'string') {
|
|
514
|
+
w.__zamesTitle = document.title.replace(/^⏳\s*/, '');
|
|
515
|
+
}
|
|
516
|
+
document.title = '⏳ ' + w.__zamesTitle;
|
|
517
|
+
}
|
|
518
|
+
else if (typeof w.__zamesTitle === 'string') {
|
|
519
|
+
document.title = w.__zamesTitle;
|
|
520
|
+
w.__zamesTitle = undefined;
|
|
521
|
+
}
|
|
522
|
+
}, busy);
|
|
523
|
+
}
|
|
524
|
+
catch { }
|
|
525
|
+
}
|
|
502
526
|
async launch() {
|
|
503
527
|
// NOTE: we deliberately do NOT kill stray chrome processes here. Per the
|
|
504
528
|
// project rules, an agent must never kill a browser it did not start —
|
|
@@ -1745,6 +1769,9 @@ export class DeepSeekBrowser {
|
|
|
1745
1769
|
}
|
|
1746
1770
|
finally {
|
|
1747
1771
|
this._askInFlight = Math.max(0, this._askInFlight - 1);
|
|
1772
|
+
// Clear the in-page "generating" marker (tab title) however the ask
|
|
1773
|
+
// ended (answer, error, abort), so it never sticks after a run.
|
|
1774
|
+
void this._setBusyTitle(false);
|
|
1748
1775
|
}
|
|
1749
1776
|
}
|
|
1750
1777
|
// Cancel an in-flight ask() whose caller (the agent-loop watchdog) already
|
|
@@ -2053,6 +2080,7 @@ export class DeepSeekBrowser {
|
|
|
2053
2080
|
catch { }
|
|
2054
2081
|
}
|
|
2055
2082
|
this._emitSendState('generating');
|
|
2083
|
+
void this._setBusyTitle(true);
|
|
2056
2084
|
this._netCapture = '';
|
|
2057
2085
|
this._netCaptureAt = 0;
|
|
2058
2086
|
this._netNoAnswer = false;
|
package/dist/index.js
CHANGED
|
@@ -18,7 +18,7 @@ import { UndoStore } from './undo.js';
|
|
|
18
18
|
import { selfReview, selfDiff, selfApply, selfList } from './self-review.js';
|
|
19
19
|
import { formatDiff, diffGitArgs, parseTranscript, summarizeTranscript, renderCost, formatExport, defaultExportPath, renderDoctor, renderPermissions, resolveExtraDir, buildReviewPrompt, formatDuration, trimRestoredMessages, RESTORED_HISTORY_LIMIT, mergeMessages, hasQueuedJob, isSlashCommand, parseQueueCommand, parseLiveToggle, parseGoalCommand, isLiveConfigCommand, withGoal, formatQueueList, ctrlCEscalation, } from './commands.js';
|
|
20
20
|
import { performCompact } from './compact.js';
|
|
21
|
-
import { Scheduler, parseInterval, formatInterval, parseCron, } from './scheduler.js';
|
|
21
|
+
import { Scheduler, parseInterval, formatInterval, formatJobLine, parseCron, } from './scheduler.js';
|
|
22
22
|
import { renderMarkdown } from './markdown.js';
|
|
23
23
|
import { closeWeb } from './web.js';
|
|
24
24
|
import { saveSession, loadLastSession, listSessions, sessionsDir, } from './sessions.js';
|
|
@@ -2456,11 +2456,7 @@ async function main() {
|
|
|
2456
2456
|
}
|
|
2457
2457
|
console.log(theme.system(t('sched.title')));
|
|
2458
2458
|
for (const j of jobs) {
|
|
2459
|
-
|
|
2460
|
-
? 'every ' + formatInterval(j.intervalMs || 0)
|
|
2461
|
-
: j.cron || '';
|
|
2462
|
-
const nextIn = formatInterval(Math.max(0, j.nextAt - Date.now()));
|
|
2463
|
-
console.log(theme.assistant(' #' + j.id + ' [' + when + ', next ~' + nextIn + '] ' + j.task));
|
|
2459
|
+
console.log(theme.assistant(formatJobLine(j, Date.now())));
|
|
2464
2460
|
}
|
|
2465
2461
|
console.log(theme.dim(t('sched.remove_hint')));
|
|
2466
2462
|
continue;
|
package/dist/scheduler.js
CHANGED
|
@@ -19,7 +19,11 @@ export function parseInterval(text) {
|
|
|
19
19
|
return n * mult;
|
|
20
20
|
}
|
|
21
21
|
// Render an interval back to the shortest human form (used in listings).
|
|
22
|
+
// Non-finite input (a cron job whose next fire could not be computed sets
|
|
23
|
+
// nextAt to Infinity) renders as "-" instead of "Infinityh".
|
|
22
24
|
export function formatInterval(ms) {
|
|
25
|
+
if (!Number.isFinite(ms))
|
|
26
|
+
return '-';
|
|
23
27
|
if (ms % 3_600_000 === 0)
|
|
24
28
|
return ms / 3_600_000 + 'h';
|
|
25
29
|
if (ms % 60_000 === 0)
|
|
@@ -111,6 +115,15 @@ export function nextCronTime(expr, fromMs) {
|
|
|
111
115
|
}
|
|
112
116
|
return null;
|
|
113
117
|
}
|
|
118
|
+
// One listing line for a job: "#3 [every 10m, next ~5m] run the tests". Pure,
|
|
119
|
+
// so the /jobs formatting is unit-tested without a live scheduler.
|
|
120
|
+
export function formatJobLine(job, now) {
|
|
121
|
+
const when = job.kind === 'loop'
|
|
122
|
+
? 'every ' + formatInterval(job.intervalMs || 0)
|
|
123
|
+
: job.cron || '';
|
|
124
|
+
const nextIn = formatInterval(Math.max(0, job.nextAt - now));
|
|
125
|
+
return ' #' + job.id + ' [' + when + ', next ~' + nextIn + '] ' + job.task;
|
|
126
|
+
}
|
|
114
127
|
// Holds the scheduled jobs. Pure: no timers here. index.ts drives it with a
|
|
115
128
|
// 1-second tick and enqueues the tasks that `due()` returns.
|
|
116
129
|
export class Scheduler {
|