harlay 0.4.0 → 0.4.1
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/app/dist/main.cjs +63 -10
- package/dist/harlay.mjs +1 -1
- package/package.json +3 -2
package/app/dist/main.cjs
CHANGED
|
@@ -3195,24 +3195,77 @@ function assessHealth(s, context) {
|
|
|
3195
3195
|
|
|
3196
3196
|
// ../../packages/core/src/webchat.ts
|
|
3197
3197
|
var import_node_path19 = require("node:path");
|
|
3198
|
+
var LIMIT_NOTICES = [
|
|
3199
|
+
// claude.ai
|
|
3200
|
+
"Usage limit reached",
|
|
3201
|
+
"You've reached your session limit",
|
|
3202
|
+
"You've reached your weekly limit",
|
|
3203
|
+
"You've reached your weekly Cowork limit",
|
|
3204
|
+
"You've reached your usage limit",
|
|
3205
|
+
"You've reached your plan's usage limit",
|
|
3206
|
+
"You've reached your monthly spend limit",
|
|
3207
|
+
"You've reached your * limit. Get more usage",
|
|
3208
|
+
"Reached your session limit",
|
|
3209
|
+
"Reached your weekly limit",
|
|
3210
|
+
"Reached your weekly Cowork limit",
|
|
3211
|
+
"Reached your usage limit",
|
|
3212
|
+
"Reached your * limit$",
|
|
3213
|
+
"* limit reached$",
|
|
3214
|
+
"Out of free messages",
|
|
3215
|
+
"You hit your message limit",
|
|
3216
|
+
"You hit your 5-hour message limit",
|
|
3217
|
+
"You hit your weekly message limit",
|
|
3218
|
+
"You hit your weekly * limit",
|
|
3219
|
+
"You hit your usage limit",
|
|
3220
|
+
"You hit the Free plan's",
|
|
3221
|
+
"You just hit your free message limit",
|
|
3222
|
+
"You've hit your limit for Claude messages",
|
|
3223
|
+
"You've hit your session limit",
|
|
3224
|
+
"You've hit your weekly limit",
|
|
3225
|
+
"You've hit your usage limit",
|
|
3226
|
+
"You've hit your monthly spend limit",
|
|
3227
|
+
"Your usage limit is still exceeded",
|
|
3228
|
+
"Paused: Your usage limit",
|
|
3229
|
+
"Limit hit. Your week resets",
|
|
3230
|
+
"Limit hit. You can send new messages",
|
|
3231
|
+
"Try again after your * resets",
|
|
3232
|
+
"Send a message after your * resets",
|
|
3233
|
+
"Wait for your * to reset",
|
|
3234
|
+
"Your * resets * Try again then",
|
|
3235
|
+
"Your * resets * Send a message then",
|
|
3236
|
+
// ChatGPT, signed out
|
|
3237
|
+
"You have reached the anonymous message limit"
|
|
3238
|
+
];
|
|
3198
3239
|
function isLimitText(s) {
|
|
3199
|
-
const
|
|
3200
|
-
if (
|
|
3201
|
-
|
|
3202
|
-
|
|
3240
|
+
const self = isLimitText;
|
|
3241
|
+
if (!self.patterns) {
|
|
3242
|
+
self.patterns = (self.notices ?? LIMIT_NOTICES).map((n) => {
|
|
3243
|
+
const whole2 = n.endsWith("$");
|
|
3244
|
+
const body = (whole2 ? n.slice(0, -1) : n).replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".{1,60}?");
|
|
3245
|
+
return new RegExp(`^${body}${whole2 ? "$" : ""}`, "i");
|
|
3246
|
+
});
|
|
3247
|
+
}
|
|
3248
|
+
const t = s.replace(/[’‘]/g, "'").replace(/\s+/g, " ").trim();
|
|
3249
|
+
if (/\b(?:upload|image|file|length|storage|project|artifact|translation|read aloud)\b/i.test(t)) return false;
|
|
3250
|
+
return t.length > 0 && t.length <= 300 && self.patterns.some((p) => p.test(t));
|
|
3203
3251
|
}
|
|
3252
|
+
var WEEKDAYS = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"];
|
|
3204
3253
|
function limitResetsAt(s, now) {
|
|
3205
3254
|
const inHours = /\bin (\d+) hours?\b/i.exec(s);
|
|
3206
3255
|
if (inHours) return new Date(now.getTime() + Number(inHours[1]) * 36e5);
|
|
3207
3256
|
const inMinutes = /\bin (\d+) min(?:ute)?s?\b/i.exec(s);
|
|
3208
3257
|
if (inMinutes) return new Date(now.getTime() + Number(inMinutes[1]) * 6e4);
|
|
3209
|
-
const m = /\b(\d{1,2})(?::(\d{2}))?\s*(am|pm)\b/i.exec(s);
|
|
3258
|
+
const m = /\b(\d{1,2})(?::(\d{2}))?\s*(am|pm)\b/i.exec(s) ?? /\b(\d{1,2}):(\d{2})\b()/.exec(s);
|
|
3210
3259
|
if (!m) return null;
|
|
3211
|
-
let h = Number(m[1])
|
|
3212
|
-
if (m[3].toLowerCase() === "pm"
|
|
3260
|
+
let h = Number(m[1]);
|
|
3261
|
+
if (m[3]) h = h % 12 + (m[3].toLowerCase() === "pm" ? 12 : 0);
|
|
3213
3262
|
const at = new Date(now);
|
|
3214
3263
|
at.setHours(h, m[2] ? Number(m[2]) : 0, 0, 0);
|
|
3215
|
-
|
|
3264
|
+
const day = /\b(sun|mon|tue|wed|thu|fri|sat)[a-z]*\b/i.exec(s);
|
|
3265
|
+
if (day) {
|
|
3266
|
+
at.setDate(at.getDate() + (WEEKDAYS.indexOf(day[1].toLowerCase()) - at.getDay() + 7) % 7);
|
|
3267
|
+
if (at.getTime() <= now.getTime()) at.setDate(at.getDate() + 7);
|
|
3268
|
+
} else if (at.getTime() <= now.getTime()) at.setDate(at.getDate() + 1);
|
|
3216
3269
|
return at;
|
|
3217
3270
|
}
|
|
3218
3271
|
function webChatTitle(c) {
|
|
@@ -3732,9 +3785,8 @@ function scanPage(root, ax, watch3, isLimit) {
|
|
|
3732
3785
|
for (const k of ax.kids(n)) walk(k, depth + 1);
|
|
3733
3786
|
};
|
|
3734
3787
|
walk(root, 0);
|
|
3735
|
-
const NOTICE = /^(?:you['’]?ve|you have|you['’]re|you are|usage limit|message limit|rate limit|limit reached)\b/i;
|
|
3736
3788
|
const tail2 = watch3 ? last ? message(last.n, last.h) : void 0 : turns.at(-1);
|
|
3737
|
-
if (tail2 && tail2.who === "agent" &&
|
|
3789
|
+
if (tail2 && tail2.who === "agent" && isLimit(tail2.text)) {
|
|
3738
3790
|
if (!limit) limit = tail2.text;
|
|
3739
3791
|
if (!watch3) turns.pop();
|
|
3740
3792
|
}
|
|
@@ -3775,6 +3827,7 @@ ObjC.bindFunction('AXUIElementCopyAttributeValue', ['int', ['id', 'id', 'id*']])
|
|
|
3775
3827
|
ObjC.bindFunction('AXUIElementSetAttributeValue', ['int', ['id', 'id', 'id']]);
|
|
3776
3828
|
ObjC.bindFunction('getppid', ['int', []]);
|
|
3777
3829
|
const isLimitText = ${isLimitText.toString()};
|
|
3830
|
+
isLimitText.notices = ${JSON.stringify(LIMIT_NOTICES)};
|
|
3778
3831
|
const scanPage = ${scanPage.toString()};
|
|
3779
3832
|
function get(el, name) { const r = Ref(); return $.AXUIElementCopyAttributeValue(el, name, r) === 0 ? r[0] : null; }
|
|
3780
3833
|
function str(v) { if (!v) return null; try { const s = ObjC.unwrap(v); return typeof s === 'string' ? s : null; } catch (e) { return null; } }
|
package/dist/harlay.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "harlay",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Move a coding task between AI agents (Claude Code, Codex, Cursor) when one stops. macOS desktop app and CLI.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"type": "module",
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
},
|
|
20
20
|
"scripts": {
|
|
21
21
|
"build": "esbuild src/bin.ts --bundle --platform=node --format=esm --target=node22 --external:@electron/packager --outfile=dist/harlay.mjs --banner:js='#!/usr/bin/env node'",
|
|
22
|
-
"prepack": "npm run build && node scripts/bundle-app.mjs"
|
|
22
|
+
"prepack": "npm run build && node scripts/bundle-app.mjs",
|
|
23
|
+
"postpack": "node -e \"require('node:fs').rmSync('app',{recursive:true,force:true})\""
|
|
23
24
|
},
|
|
24
25
|
"dependencies": {
|
|
25
26
|
"@electron/packager": "^20.3.0"
|