terminalhire 0.42.4 → 0.42.5
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/bin/founder-bounty-notify.js +117 -0
- package/dist/bin/jpi-bounties.js +6 -1
- package/dist/bin/jpi-chat-read.js +2 -1
- package/dist/bin/jpi-chat.js +2 -1
- package/dist/bin/jpi-config.js +167 -20
- package/dist/bin/jpi-contribute.js +2 -1
- package/dist/bin/jpi-dispatch.js +176 -6
- package/dist/bin/jpi-hub.js +2 -1
- package/dist/bin/jpi-inbox.js +2 -1
- package/dist/bin/jpi-jobs.js +6 -1
- package/dist/bin/jpi-link.js +2 -1
- package/dist/bin/jpi-login.js +2 -1
- package/dist/bin/jpi-mcp-chat.js +2 -1
- package/dist/bin/jpi-mcp.js +6 -1
- package/dist/bin/jpi-refresh.js +128 -1
- package/dist/bin/peer-connect-prompt.js +2 -1
- package/dist/bin/pulse-prompt.js +2 -1
- package/dist/src/config.js +6 -1
- package/dist/src/link.js +2 -1
- package/package.json +1 -1
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// bin/founder-bounty-notify.js
|
|
2
|
+
import { spawn } from "child_process";
|
|
3
|
+
|
|
4
|
+
// bin/founder-pin.js
|
|
5
|
+
function isPinnedFounderBounty(j) {
|
|
6
|
+
return j?.bounty?.bountySource === "founder" && j?.bounty?.claimable === true;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// bin/founder-paid-badge.js
|
|
10
|
+
function openPaidIds(index) {
|
|
11
|
+
const jobs = index && index.jobs || [];
|
|
12
|
+
const ids = [];
|
|
13
|
+
for (const j of jobs) {
|
|
14
|
+
if (!j || typeof j.id !== "string") continue;
|
|
15
|
+
if (isPinnedFounderBounty(j)) ids.push(j.id);
|
|
16
|
+
}
|
|
17
|
+
return [...new Set(ids)].sort();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// bin/founder-bounty-notify.js
|
|
21
|
+
function nextFounderBountyNotifyState(index, previous) {
|
|
22
|
+
const open = openPaidIds(index);
|
|
23
|
+
const prior = previous && Array.isArray(previous.ids) ? previous.ids : null;
|
|
24
|
+
if (prior === null) {
|
|
25
|
+
return { ids: open, fire: [], seeded: true };
|
|
26
|
+
}
|
|
27
|
+
const seen = new Set(prior);
|
|
28
|
+
const fire = open.filter((id) => !seen.has(id));
|
|
29
|
+
const ids = [.../* @__PURE__ */ new Set([...prior.filter((id) => open.includes(id)), ...fire])].sort();
|
|
30
|
+
return { ids, fire, seeded: false };
|
|
31
|
+
}
|
|
32
|
+
function formatFounderBountyNotifyBody(index, fireIds) {
|
|
33
|
+
const jobs = index && index.jobs || [];
|
|
34
|
+
const byId = /* @__PURE__ */ new Map();
|
|
35
|
+
for (const j of jobs) {
|
|
36
|
+
if (j && typeof j.id === "string") byId.set(j.id, j);
|
|
37
|
+
}
|
|
38
|
+
if (fireIds.length === 1) {
|
|
39
|
+
const j = byId.get(fireIds[0]);
|
|
40
|
+
const amount = j && j.bounty && typeof j.bounty.amountUSD === "number" ? j.bounty.amountUSD : null;
|
|
41
|
+
const price = typeof amount === "number" && Number.isFinite(amount) && amount > 0 ? `$${Math.round(amount)} ` : "";
|
|
42
|
+
return `${price}founder bounty available \u2014 run: terminalhire bounties`;
|
|
43
|
+
}
|
|
44
|
+
return `${fireIds.length} founder bounties available \u2014 run: terminalhire bounties`;
|
|
45
|
+
}
|
|
46
|
+
function escapeAppleScriptString(s) {
|
|
47
|
+
return String(s).replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
48
|
+
}
|
|
49
|
+
function displayLocalNotification({
|
|
50
|
+
title = "Terminalhire",
|
|
51
|
+
body,
|
|
52
|
+
platform = process.platform,
|
|
53
|
+
spawnFn = spawn
|
|
54
|
+
} = {}) {
|
|
55
|
+
if (!body || typeof body !== "string") return false;
|
|
56
|
+
try {
|
|
57
|
+
if (platform === "darwin") {
|
|
58
|
+
const t = escapeAppleScriptString(title);
|
|
59
|
+
const b = escapeAppleScriptString(body);
|
|
60
|
+
const child = spawnFn("osascript", ["-e", `display notification "${b}" with title "${t}"`], {
|
|
61
|
+
detached: true,
|
|
62
|
+
stdio: "ignore"
|
|
63
|
+
});
|
|
64
|
+
if (child && typeof child.unref === "function") child.unref();
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
if (platform === "win32") {
|
|
68
|
+
const safeTitle = String(title).replace(/'/g, "''");
|
|
69
|
+
const safeBody = String(body).replace(/'/g, "''");
|
|
70
|
+
const ps = `
|
|
71
|
+
Add-Type -AssemblyName System.Windows.Forms
|
|
72
|
+
$n = New-Object System.Windows.Forms.NotifyIcon
|
|
73
|
+
$n.Icon = [System.Drawing.SystemIcons]::Information
|
|
74
|
+
$n.Visible = $true
|
|
75
|
+
$n.ShowBalloonTip(8000, '${safeTitle}', '${safeBody}', [System.Windows.Forms.ToolTipIcon]::Info)
|
|
76
|
+
Start-Sleep -Seconds 9
|
|
77
|
+
$n.Dispose()
|
|
78
|
+
`.trim();
|
|
79
|
+
const child = spawnFn("powershell.exe", ["-NoProfile", "-Command", ps], {
|
|
80
|
+
detached: true,
|
|
81
|
+
stdio: "ignore",
|
|
82
|
+
windowsHide: true
|
|
83
|
+
});
|
|
84
|
+
if (child && typeof child.unref === "function") child.unref();
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
return false;
|
|
88
|
+
} catch {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function maybeNotifyFounderBounties({
|
|
93
|
+
index,
|
|
94
|
+
previous,
|
|
95
|
+
optedIn,
|
|
96
|
+
display = displayLocalNotification
|
|
97
|
+
} = {}) {
|
|
98
|
+
if (!optedIn) {
|
|
99
|
+
const ids = previous && Array.isArray(previous.ids) ? [...previous.ids].sort() : [];
|
|
100
|
+
return { state: { ids }, fired: [] };
|
|
101
|
+
}
|
|
102
|
+
const next = nextFounderBountyNotifyState(index, previous);
|
|
103
|
+
if (next.fire.length > 0) {
|
|
104
|
+
display({
|
|
105
|
+
title: "Terminalhire",
|
|
106
|
+
body: formatFounderBountyNotifyBody(index, next.fire)
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
return { state: { ids: next.ids }, fired: next.fire };
|
|
110
|
+
}
|
|
111
|
+
export {
|
|
112
|
+
displayLocalNotification,
|
|
113
|
+
escapeAppleScriptString,
|
|
114
|
+
formatFounderBountyNotifyBody,
|
|
115
|
+
maybeNotifyFounderBounties,
|
|
116
|
+
nextFounderBountyNotifyState
|
|
117
|
+
};
|
package/dist/bin/jpi-bounties.js
CHANGED
|
@@ -11546,6 +11546,7 @@ __export(config_exports, {
|
|
|
11546
11546
|
getSurfaceMix: () => getSurfaceMix,
|
|
11547
11547
|
isBetaOptIn: () => isBetaOptIn,
|
|
11548
11548
|
isContributeEnabled: () => isContributeEnabled,
|
|
11549
|
+
isFounderBountyNotifyEnabled: () => isFounderBountyNotifyEnabled,
|
|
11549
11550
|
isInboundNudgeMuted: () => isInboundNudgeMuted,
|
|
11550
11551
|
isPeerConnectEnabled: () => isPeerConnectEnabled,
|
|
11551
11552
|
parseNudgeMode: () => parseNudgeMode,
|
|
@@ -11630,6 +11631,9 @@ function isContributeEnabled() {
|
|
|
11630
11631
|
function isBetaOptIn() {
|
|
11631
11632
|
return readConfig().betaOptIn === true;
|
|
11632
11633
|
}
|
|
11634
|
+
function isFounderBountyNotifyEnabled() {
|
|
11635
|
+
return readConfig().founderBountyNotify === true;
|
|
11636
|
+
}
|
|
11633
11637
|
var TERMINALHIRE_DIR6, CONFIG_FILE, DEFAULT_CONFIG;
|
|
11634
11638
|
var init_config = __esm({
|
|
11635
11639
|
"src/config.ts"() {
|
|
@@ -11651,7 +11655,8 @@ var init_config = __esm({
|
|
|
11651
11655
|
lastFullFeedbackAt: null,
|
|
11652
11656
|
lastPulseAskAt: null,
|
|
11653
11657
|
pulseDisclosed: false,
|
|
11654
|
-
mix: "balanced"
|
|
11658
|
+
mix: "balanced",
|
|
11659
|
+
founderBountyNotify: false
|
|
11655
11660
|
};
|
|
11656
11661
|
}
|
|
11657
11662
|
});
|
package/dist/bin/jpi-chat.js
CHANGED
package/dist/bin/jpi-config.js
CHANGED
|
@@ -1,21 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __esm = (fn, res) => function __init() {
|
|
5
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
6
|
+
};
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
11
|
|
|
12
12
|
// src/state-dir.ts
|
|
13
13
|
import { closeSync, constants, fchmodSync, fstatSync, mkdirSync, openSync } from "fs";
|
|
14
|
-
var STATE_DIR_MODE = 448;
|
|
15
|
-
var STATE_DIR_OK = "ok";
|
|
16
|
-
var STATE_DIR_SYMLINK = "symlink";
|
|
17
|
-
var STATE_DIR_UNVERIFIED = "unverified";
|
|
18
|
-
var warnedDirs = /* @__PURE__ */ new Set();
|
|
19
14
|
function warnStateDirOnce(dir, message) {
|
|
20
15
|
if (warnedDirs.has(dir)) return;
|
|
21
16
|
warnedDirs.add(dir);
|
|
@@ -56,8 +51,116 @@ function ensureStateDir(dir) {
|
|
|
56
51
|
}
|
|
57
52
|
}
|
|
58
53
|
}
|
|
54
|
+
var STATE_DIR_MODE, STATE_DIR_OK, STATE_DIR_SYMLINK, STATE_DIR_UNVERIFIED, warnedDirs;
|
|
55
|
+
var init_state_dir = __esm({
|
|
56
|
+
"src/state-dir.ts"() {
|
|
57
|
+
"use strict";
|
|
58
|
+
STATE_DIR_MODE = 448;
|
|
59
|
+
STATE_DIR_OK = "ok";
|
|
60
|
+
STATE_DIR_SYMLINK = "symlink";
|
|
61
|
+
STATE_DIR_UNVERIFIED = "unverified";
|
|
62
|
+
warnedDirs = /* @__PURE__ */ new Set();
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// bin/founder-pin.js
|
|
67
|
+
function isPinnedFounderBounty(j) {
|
|
68
|
+
return j?.bounty?.bountySource === "founder" && j?.bounty?.claimable === true;
|
|
69
|
+
}
|
|
70
|
+
var init_founder_pin = __esm({
|
|
71
|
+
"bin/founder-pin.js"() {
|
|
72
|
+
"use strict";
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// bin/founder-paid-badge.js
|
|
77
|
+
var founder_paid_badge_exports = {};
|
|
78
|
+
__export(founder_paid_badge_exports, {
|
|
79
|
+
acknowledgeFounderPaid: () => acknowledgeFounderPaid,
|
|
80
|
+
computeFounderPaid: () => computeFounderPaid,
|
|
81
|
+
openPaidIds: () => openPaidIds
|
|
82
|
+
});
|
|
83
|
+
function openPaidIds(index) {
|
|
84
|
+
const jobs = index && index.jobs || [];
|
|
85
|
+
const ids = [];
|
|
86
|
+
for (const j of jobs) {
|
|
87
|
+
if (!j || typeof j.id !== "string") continue;
|
|
88
|
+
if (isPinnedFounderBounty(j)) ids.push(j.id);
|
|
89
|
+
}
|
|
90
|
+
return [...new Set(ids)].sort();
|
|
91
|
+
}
|
|
92
|
+
function gate(openIds, seenIds) {
|
|
93
|
+
const seen = new Set(seenIds);
|
|
94
|
+
const acknowledged = openIds.filter((id) => seen.has(id));
|
|
95
|
+
return { count: openIds.length - acknowledged.length, acknowledged };
|
|
96
|
+
}
|
|
97
|
+
function computeFounderPaid(index, previous) {
|
|
98
|
+
const open = openPaidIds(index);
|
|
99
|
+
const prior = previous && previous.acknowledged;
|
|
100
|
+
return gate(open, Array.isArray(prior) ? prior : []);
|
|
101
|
+
}
|
|
102
|
+
function acknowledgeFounderPaid({ shown = [], open = [], previous } = {}) {
|
|
103
|
+
const prior = previous && Array.isArray(previous.acknowledged) ? previous.acknowledged : [];
|
|
104
|
+
return gate(openPaidIds({ jobs: open }), [...prior, ...openPaidIds({ jobs: shown })]);
|
|
105
|
+
}
|
|
106
|
+
var init_founder_paid_badge = __esm({
|
|
107
|
+
"bin/founder-paid-badge.js"() {
|
|
108
|
+
"use strict";
|
|
109
|
+
init_founder_pin();
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// bin/cache-store.js
|
|
114
|
+
var cache_store_exports = {};
|
|
115
|
+
__export(cache_store_exports, {
|
|
116
|
+
readCacheEntry: () => readCacheEntry,
|
|
117
|
+
updateIndexCache: () => updateIndexCache
|
|
118
|
+
});
|
|
119
|
+
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, renameSync } from "fs";
|
|
120
|
+
import { join as join2 } from "path";
|
|
121
|
+
import { homedir as homedir2 } from "os";
|
|
122
|
+
function readCacheEntry() {
|
|
123
|
+
try {
|
|
124
|
+
return JSON.parse(readFileSync2(INDEX_CACHE_FILE, "utf8"));
|
|
125
|
+
} catch {
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function updateIndexCache(patch) {
|
|
130
|
+
ensureStateDir(TERMINALHIRE_DIR2);
|
|
131
|
+
const existing = readCacheEntry() ?? {};
|
|
132
|
+
const entry = {
|
|
133
|
+
...existing,
|
|
134
|
+
...patch,
|
|
135
|
+
schemaVersion: SCHEMA_VERSION,
|
|
136
|
+
ts: Date.now()
|
|
137
|
+
};
|
|
138
|
+
const tmp = `${INDEX_CACHE_FILE}.${process.pid}.${tmpCounter++}.tmp`;
|
|
139
|
+
writeFileSync2(tmp, JSON.stringify(entry), "utf8");
|
|
140
|
+
renameSync(tmp, INDEX_CACHE_FILE);
|
|
141
|
+
return entry;
|
|
142
|
+
}
|
|
143
|
+
var TERMINALHIRE_DIR2, INDEX_CACHE_FILE, SCHEMA_VERSION, tmpCounter;
|
|
144
|
+
var init_cache_store = __esm({
|
|
145
|
+
"bin/cache-store.js"() {
|
|
146
|
+
"use strict";
|
|
147
|
+
init_state_dir();
|
|
148
|
+
TERMINALHIRE_DIR2 = process.env.TERMINALHIRE_DIR || join2(homedir2(), ".terminalhire");
|
|
149
|
+
INDEX_CACHE_FILE = join2(TERMINALHIRE_DIR2, "index-cache.json");
|
|
150
|
+
SCHEMA_VERSION = 1;
|
|
151
|
+
tmpCounter = 0;
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// bin/jpi-config.js
|
|
156
|
+
import { join as join3 } from "path";
|
|
157
|
+
import { homedir as homedir3 } from "os";
|
|
59
158
|
|
|
60
159
|
// src/config.ts
|
|
160
|
+
init_state_dir();
|
|
161
|
+
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
162
|
+
import { join } from "path";
|
|
163
|
+
import { homedir } from "os";
|
|
61
164
|
var TERMINALHIRE_DIR = process.env.TERMINALHIRE_DIR || join(homedir(), ".terminalhire");
|
|
62
165
|
var CONFIG_FILE = join(TERMINALHIRE_DIR, "config.json");
|
|
63
166
|
var DEFAULT_CONFIG = {
|
|
@@ -74,7 +177,8 @@ var DEFAULT_CONFIG = {
|
|
|
74
177
|
lastFullFeedbackAt: null,
|
|
75
178
|
lastPulseAskAt: null,
|
|
76
179
|
pulseDisclosed: false,
|
|
77
|
-
mix: "balanced"
|
|
180
|
+
mix: "balanced",
|
|
181
|
+
founderBountyNotify: false
|
|
78
182
|
};
|
|
79
183
|
function readConfig() {
|
|
80
184
|
try {
|
|
@@ -107,8 +211,8 @@ function parseSurfaceLead(raw) {
|
|
|
107
211
|
}
|
|
108
212
|
|
|
109
213
|
// bin/jpi-config.js
|
|
110
|
-
var
|
|
111
|
-
var CONFIG_FILE2 =
|
|
214
|
+
var TERMINALHIRE_DIR3 = process.env.TERMINALHIRE_DIR || join3(homedir3(), ".terminalhire");
|
|
215
|
+
var CONFIG_FILE2 = join3(TERMINALHIRE_DIR3, "config.json");
|
|
112
216
|
function parseNudgeMode(raw) {
|
|
113
217
|
if (raw === "session" || raw === "always") return raw;
|
|
114
218
|
const m = /^every:(\d+)$/.exec(raw);
|
|
@@ -186,13 +290,20 @@ async function run() {
|
|
|
186
290
|
if (envOverride) {
|
|
187
291
|
console.log(` (overridden by TERMINALHIRE_NUDGE=${envOverride} at runtime)`);
|
|
188
292
|
}
|
|
189
|
-
console.log(
|
|
293
|
+
console.log(
|
|
294
|
+
` peer-connect: ${cfg.peerConnect ? "on" : "off"} (ambient peer & founder surfacing; default off)`
|
|
295
|
+
);
|
|
190
296
|
const mixEnv = process.env["TH_MIX"];
|
|
191
|
-
console.log(
|
|
297
|
+
console.log(
|
|
298
|
+
` mix: ${cfg.mix} (roles vs. contributions on the ambient surface; default balanced)`
|
|
299
|
+
);
|
|
192
300
|
if (mixEnv) {
|
|
193
301
|
console.log(` (mix overridden by TH_MIX=${mixEnv} at runtime)`);
|
|
194
302
|
}
|
|
195
303
|
console.log(` lead: ${cfg.surfaceLead ?? "auto"} (auto derives from your open postings)`);
|
|
304
|
+
console.log(
|
|
305
|
+
` founder-notify: ${cfg.founderBountyNotify ? "on" : "off"} (OS ping when a paid founder bounty drops; default off)`
|
|
306
|
+
);
|
|
196
307
|
console.log(` config file: ${CONFIG_FILE2}`);
|
|
197
308
|
console.log("");
|
|
198
309
|
console.log(" Valid nudge values:");
|
|
@@ -204,9 +315,15 @@ async function run() {
|
|
|
204
315
|
console.log(" (set with: config set mix <value> \xB7 read with: config get mix)");
|
|
205
316
|
console.log("");
|
|
206
317
|
console.log(" Peer-connect (--connect on|off):");
|
|
207
|
-
console.log(
|
|
318
|
+
console.log(
|
|
319
|
+
" on \u2014 surface peers & founders in the spinner + send an anonymous matched signal"
|
|
320
|
+
);
|
|
208
321
|
console.log(" off \u2014 no peer matching, no directory fetch, no signal (default)");
|
|
209
322
|
console.log("");
|
|
323
|
+
console.log(" Founder bounty OS notify (--founder-notify on|off):");
|
|
324
|
+
console.log(" on \u2014 ping when a NEW claimable founder bounty appears (TERM-228)");
|
|
325
|
+
console.log(" off \u2014 no OS toast for founder supply (default)");
|
|
326
|
+
console.log("");
|
|
210
327
|
return;
|
|
211
328
|
}
|
|
212
329
|
const nudgeIdx = filtered.indexOf("--nudge");
|
|
@@ -238,8 +355,38 @@ async function run() {
|
|
|
238
355
|
console.log(` (saved to ${CONFIG_FILE2})`);
|
|
239
356
|
return;
|
|
240
357
|
}
|
|
358
|
+
const founderNotifyIdx = filtered.indexOf("--founder-notify");
|
|
359
|
+
if (founderNotifyIdx !== -1) {
|
|
360
|
+
const value = filtered[founderNotifyIdx + 1];
|
|
361
|
+
if (value !== "on" && value !== "off") {
|
|
362
|
+
console.error("Error: --founder-notify requires a value: on | off");
|
|
363
|
+
process.exit(1);
|
|
364
|
+
}
|
|
365
|
+
writeConfig({ founderBountyNotify: value === "on" });
|
|
366
|
+
if (value === "on") {
|
|
367
|
+
try {
|
|
368
|
+
const { openPaidIds: openPaidIds2 } = await Promise.resolve().then(() => (init_founder_paid_badge(), founder_paid_badge_exports));
|
|
369
|
+
const { readCacheEntry: readCacheEntry2, updateIndexCache: updateIndexCache2 } = await Promise.resolve().then(() => (init_cache_store(), cache_store_exports));
|
|
370
|
+
const entry = readCacheEntry2() ?? {};
|
|
371
|
+
const ids = openPaidIds2(entry.index);
|
|
372
|
+
updateIndexCache2({ founderPaidOsNotified: { ids } });
|
|
373
|
+
console.log(` founder-notify set to: on`);
|
|
374
|
+
console.log(
|
|
375
|
+
` (seeded ${ids.length} existing open bounty id(s) \u2014 only NEW ones will ping)`
|
|
376
|
+
);
|
|
377
|
+
} catch {
|
|
378
|
+
console.log(` founder-notify set to: on`);
|
|
379
|
+
console.log(" (could not seed from cache \u2014 first refresh will silent-seed)");
|
|
380
|
+
}
|
|
381
|
+
} else {
|
|
382
|
+
console.log(` founder-notify set to: off`);
|
|
383
|
+
}
|
|
384
|
+
console.log(` (saved to ${CONFIG_FILE2})`);
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
241
387
|
console.error("Usage: terminalhire config --nudge <session|always|every:N>");
|
|
242
388
|
console.error(" terminalhire config --connect <on|off>");
|
|
389
|
+
console.error(" terminalhire config --founder-notify <on|off>");
|
|
243
390
|
console.error(" terminalhire config set mix <jobs|balanced|credential>");
|
|
244
391
|
console.error(" terminalhire config get mix");
|
|
245
392
|
console.error(" terminalhire config set lead <auto|dev|founder>");
|
package/dist/bin/jpi-dispatch.js
CHANGED
|
@@ -175,6 +175,7 @@ __export(config_exports, {
|
|
|
175
175
|
getSurfaceMix: () => getSurfaceMix,
|
|
176
176
|
isBetaOptIn: () => isBetaOptIn,
|
|
177
177
|
isContributeEnabled: () => isContributeEnabled,
|
|
178
|
+
isFounderBountyNotifyEnabled: () => isFounderBountyNotifyEnabled,
|
|
178
179
|
isInboundNudgeMuted: () => isInboundNudgeMuted,
|
|
179
180
|
isPeerConnectEnabled: () => isPeerConnectEnabled,
|
|
180
181
|
parseNudgeMode: () => parseNudgeMode,
|
|
@@ -259,6 +260,9 @@ function isContributeEnabled() {
|
|
|
259
260
|
function isBetaOptIn() {
|
|
260
261
|
return readConfig().betaOptIn === true;
|
|
261
262
|
}
|
|
263
|
+
function isFounderBountyNotifyEnabled() {
|
|
264
|
+
return readConfig().founderBountyNotify === true;
|
|
265
|
+
}
|
|
262
266
|
var TERMINALHIRE_DIR, CONFIG_FILE, DEFAULT_CONFIG;
|
|
263
267
|
var init_config = __esm({
|
|
264
268
|
"src/config.ts"() {
|
|
@@ -280,7 +284,8 @@ var init_config = __esm({
|
|
|
280
284
|
lastFullFeedbackAt: null,
|
|
281
285
|
lastPulseAskAt: null,
|
|
282
286
|
pulseDisclosed: false,
|
|
283
|
-
mix: "balanced"
|
|
287
|
+
mix: "balanced",
|
|
288
|
+
founderBountyNotify: false
|
|
284
289
|
};
|
|
285
290
|
}
|
|
286
291
|
});
|
|
@@ -30923,8 +30928,8 @@ function shStream(cmd, args5, opts = {}) {
|
|
|
30923
30928
|
const cap = opts.maxStderrBytes ?? 64 * 1024;
|
|
30924
30929
|
return new Promise((resolve7, reject) => {
|
|
30925
30930
|
void (async () => {
|
|
30926
|
-
const
|
|
30927
|
-
const child =
|
|
30931
|
+
const spawn5 = opts.spawnFn ?? (await import("child_process")).spawn;
|
|
30932
|
+
const child = spawn5(cmd, args5, { shell: false, stdio: ["ignore", "pipe", "pipe"] });
|
|
30928
30933
|
let stdout = "";
|
|
30929
30934
|
let stderr = "";
|
|
30930
30935
|
child.stdout?.setEncoding("utf8");
|
|
@@ -65167,13 +65172,20 @@ async function run24() {
|
|
|
65167
65172
|
if (envOverride) {
|
|
65168
65173
|
console.log(` (overridden by TERMINALHIRE_NUDGE=${envOverride} at runtime)`);
|
|
65169
65174
|
}
|
|
65170
|
-
console.log(
|
|
65175
|
+
console.log(
|
|
65176
|
+
` peer-connect: ${cfg.peerConnect ? "on" : "off"} (ambient peer & founder surfacing; default off)`
|
|
65177
|
+
);
|
|
65171
65178
|
const mixEnv = process.env["TH_MIX"];
|
|
65172
|
-
console.log(
|
|
65179
|
+
console.log(
|
|
65180
|
+
` mix: ${cfg.mix} (roles vs. contributions on the ambient surface; default balanced)`
|
|
65181
|
+
);
|
|
65173
65182
|
if (mixEnv) {
|
|
65174
65183
|
console.log(` (mix overridden by TH_MIX=${mixEnv} at runtime)`);
|
|
65175
65184
|
}
|
|
65176
65185
|
console.log(` lead: ${cfg.surfaceLead ?? "auto"} (auto derives from your open postings)`);
|
|
65186
|
+
console.log(
|
|
65187
|
+
` founder-notify: ${cfg.founderBountyNotify ? "on" : "off"} (OS ping when a paid founder bounty drops; default off)`
|
|
65188
|
+
);
|
|
65177
65189
|
console.log(` config file: ${CONFIG_FILE2}`);
|
|
65178
65190
|
console.log("");
|
|
65179
65191
|
console.log(" Valid nudge values:");
|
|
@@ -65185,9 +65197,15 @@ async function run24() {
|
|
|
65185
65197
|
console.log(" (set with: config set mix <value> \xB7 read with: config get mix)");
|
|
65186
65198
|
console.log("");
|
|
65187
65199
|
console.log(" Peer-connect (--connect on|off):");
|
|
65188
|
-
console.log(
|
|
65200
|
+
console.log(
|
|
65201
|
+
" on \u2014 surface peers & founders in the spinner + send an anonymous matched signal"
|
|
65202
|
+
);
|
|
65189
65203
|
console.log(" off \u2014 no peer matching, no directory fetch, no signal (default)");
|
|
65190
65204
|
console.log("");
|
|
65205
|
+
console.log(" Founder bounty OS notify (--founder-notify on|off):");
|
|
65206
|
+
console.log(" on \u2014 ping when a NEW claimable founder bounty appears (TERM-228)");
|
|
65207
|
+
console.log(" off \u2014 no OS toast for founder supply (default)");
|
|
65208
|
+
console.log("");
|
|
65191
65209
|
return;
|
|
65192
65210
|
}
|
|
65193
65211
|
const nudgeIdx = filtered.indexOf("--nudge");
|
|
@@ -65219,8 +65237,38 @@ async function run24() {
|
|
|
65219
65237
|
console.log(` (saved to ${CONFIG_FILE2})`);
|
|
65220
65238
|
return;
|
|
65221
65239
|
}
|
|
65240
|
+
const founderNotifyIdx = filtered.indexOf("--founder-notify");
|
|
65241
|
+
if (founderNotifyIdx !== -1) {
|
|
65242
|
+
const value = filtered[founderNotifyIdx + 1];
|
|
65243
|
+
if (value !== "on" && value !== "off") {
|
|
65244
|
+
console.error("Error: --founder-notify requires a value: on | off");
|
|
65245
|
+
process.exit(1);
|
|
65246
|
+
}
|
|
65247
|
+
writeConfig({ founderBountyNotify: value === "on" });
|
|
65248
|
+
if (value === "on") {
|
|
65249
|
+
try {
|
|
65250
|
+
const { openPaidIds: openPaidIds2 } = await Promise.resolve().then(() => (init_founder_paid_badge(), founder_paid_badge_exports));
|
|
65251
|
+
const { readCacheEntry: readCacheEntry2, updateIndexCache: updateIndexCache2 } = await Promise.resolve().then(() => (init_cache_store(), cache_store_exports));
|
|
65252
|
+
const entry = readCacheEntry2() ?? {};
|
|
65253
|
+
const ids = openPaidIds2(entry.index);
|
|
65254
|
+
updateIndexCache2({ founderPaidOsNotified: { ids } });
|
|
65255
|
+
console.log(` founder-notify set to: on`);
|
|
65256
|
+
console.log(
|
|
65257
|
+
` (seeded ${ids.length} existing open bounty id(s) \u2014 only NEW ones will ping)`
|
|
65258
|
+
);
|
|
65259
|
+
} catch {
|
|
65260
|
+
console.log(` founder-notify set to: on`);
|
|
65261
|
+
console.log(" (could not seed from cache \u2014 first refresh will silent-seed)");
|
|
65262
|
+
}
|
|
65263
|
+
} else {
|
|
65264
|
+
console.log(` founder-notify set to: off`);
|
|
65265
|
+
}
|
|
65266
|
+
console.log(` (saved to ${CONFIG_FILE2})`);
|
|
65267
|
+
return;
|
|
65268
|
+
}
|
|
65222
65269
|
console.error("Usage: terminalhire config --nudge <session|always|every:N>");
|
|
65223
65270
|
console.error(" terminalhire config --connect <on|off>");
|
|
65271
|
+
console.error(" terminalhire config --founder-notify <on|off>");
|
|
65224
65272
|
console.error(" terminalhire config set mix <jobs|balanced|credential>");
|
|
65225
65273
|
console.error(" terminalhire config get mix");
|
|
65226
65274
|
console.error(" terminalhire config set lead <auto|dev|founder>");
|
|
@@ -66187,6 +66235,113 @@ var init_job_status_suppress = __esm({
|
|
|
66187
66235
|
}
|
|
66188
66236
|
});
|
|
66189
66237
|
|
|
66238
|
+
// bin/founder-bounty-notify.js
|
|
66239
|
+
var founder_bounty_notify_exports = {};
|
|
66240
|
+
__export(founder_bounty_notify_exports, {
|
|
66241
|
+
displayLocalNotification: () => displayLocalNotification,
|
|
66242
|
+
escapeAppleScriptString: () => escapeAppleScriptString2,
|
|
66243
|
+
formatFounderBountyNotifyBody: () => formatFounderBountyNotifyBody,
|
|
66244
|
+
maybeNotifyFounderBounties: () => maybeNotifyFounderBounties,
|
|
66245
|
+
nextFounderBountyNotifyState: () => nextFounderBountyNotifyState
|
|
66246
|
+
});
|
|
66247
|
+
import { spawn as spawn4 } from "child_process";
|
|
66248
|
+
function nextFounderBountyNotifyState(index, previous) {
|
|
66249
|
+
const open3 = openPaidIds(index);
|
|
66250
|
+
const prior = previous && Array.isArray(previous.ids) ? previous.ids : null;
|
|
66251
|
+
if (prior === null) {
|
|
66252
|
+
return { ids: open3, fire: [], seeded: true };
|
|
66253
|
+
}
|
|
66254
|
+
const seen = new Set(prior);
|
|
66255
|
+
const fire = open3.filter((id) => !seen.has(id));
|
|
66256
|
+
const ids = [.../* @__PURE__ */ new Set([...prior.filter((id) => open3.includes(id)), ...fire])].sort();
|
|
66257
|
+
return { ids, fire, seeded: false };
|
|
66258
|
+
}
|
|
66259
|
+
function formatFounderBountyNotifyBody(index, fireIds) {
|
|
66260
|
+
const jobs = index && index.jobs || [];
|
|
66261
|
+
const byId = /* @__PURE__ */ new Map();
|
|
66262
|
+
for (const j of jobs) {
|
|
66263
|
+
if (j && typeof j.id === "string") byId.set(j.id, j);
|
|
66264
|
+
}
|
|
66265
|
+
if (fireIds.length === 1) {
|
|
66266
|
+
const j = byId.get(fireIds[0]);
|
|
66267
|
+
const amount = j && j.bounty && typeof j.bounty.amountUSD === "number" ? j.bounty.amountUSD : null;
|
|
66268
|
+
const price = typeof amount === "number" && Number.isFinite(amount) && amount > 0 ? `$${Math.round(amount)} ` : "";
|
|
66269
|
+
return `${price}founder bounty available \u2014 run: terminalhire bounties`;
|
|
66270
|
+
}
|
|
66271
|
+
return `${fireIds.length} founder bounties available \u2014 run: terminalhire bounties`;
|
|
66272
|
+
}
|
|
66273
|
+
function escapeAppleScriptString2(s) {
|
|
66274
|
+
return String(s).replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
66275
|
+
}
|
|
66276
|
+
function displayLocalNotification({
|
|
66277
|
+
title = "Terminalhire",
|
|
66278
|
+
body,
|
|
66279
|
+
platform = process.platform,
|
|
66280
|
+
spawnFn = spawn4
|
|
66281
|
+
} = {}) {
|
|
66282
|
+
if (!body || typeof body !== "string") return false;
|
|
66283
|
+
try {
|
|
66284
|
+
if (platform === "darwin") {
|
|
66285
|
+
const t = escapeAppleScriptString2(title);
|
|
66286
|
+
const b = escapeAppleScriptString2(body);
|
|
66287
|
+
const child = spawnFn("osascript", ["-e", `display notification "${b}" with title "${t}"`], {
|
|
66288
|
+
detached: true,
|
|
66289
|
+
stdio: "ignore"
|
|
66290
|
+
});
|
|
66291
|
+
if (child && typeof child.unref === "function") child.unref();
|
|
66292
|
+
return true;
|
|
66293
|
+
}
|
|
66294
|
+
if (platform === "win32") {
|
|
66295
|
+
const safeTitle = String(title).replace(/'/g, "''");
|
|
66296
|
+
const safeBody = String(body).replace(/'/g, "''");
|
|
66297
|
+
const ps = `
|
|
66298
|
+
Add-Type -AssemblyName System.Windows.Forms
|
|
66299
|
+
$n = New-Object System.Windows.Forms.NotifyIcon
|
|
66300
|
+
$n.Icon = [System.Drawing.SystemIcons]::Information
|
|
66301
|
+
$n.Visible = $true
|
|
66302
|
+
$n.ShowBalloonTip(8000, '${safeTitle}', '${safeBody}', [System.Windows.Forms.ToolTipIcon]::Info)
|
|
66303
|
+
Start-Sleep -Seconds 9
|
|
66304
|
+
$n.Dispose()
|
|
66305
|
+
`.trim();
|
|
66306
|
+
const child = spawnFn("powershell.exe", ["-NoProfile", "-Command", ps], {
|
|
66307
|
+
detached: true,
|
|
66308
|
+
stdio: "ignore",
|
|
66309
|
+
windowsHide: true
|
|
66310
|
+
});
|
|
66311
|
+
if (child && typeof child.unref === "function") child.unref();
|
|
66312
|
+
return true;
|
|
66313
|
+
}
|
|
66314
|
+
return false;
|
|
66315
|
+
} catch {
|
|
66316
|
+
return false;
|
|
66317
|
+
}
|
|
66318
|
+
}
|
|
66319
|
+
function maybeNotifyFounderBounties({
|
|
66320
|
+
index,
|
|
66321
|
+
previous,
|
|
66322
|
+
optedIn,
|
|
66323
|
+
display = displayLocalNotification
|
|
66324
|
+
} = {}) {
|
|
66325
|
+
if (!optedIn) {
|
|
66326
|
+
const ids = previous && Array.isArray(previous.ids) ? [...previous.ids].sort() : [];
|
|
66327
|
+
return { state: { ids }, fired: [] };
|
|
66328
|
+
}
|
|
66329
|
+
const next = nextFounderBountyNotifyState(index, previous);
|
|
66330
|
+
if (next.fire.length > 0) {
|
|
66331
|
+
display({
|
|
66332
|
+
title: "Terminalhire",
|
|
66333
|
+
body: formatFounderBountyNotifyBody(index, next.fire)
|
|
66334
|
+
});
|
|
66335
|
+
}
|
|
66336
|
+
return { state: { ids: next.ids }, fired: next.fire };
|
|
66337
|
+
}
|
|
66338
|
+
var init_founder_bounty_notify = __esm({
|
|
66339
|
+
"bin/founder-bounty-notify.js"() {
|
|
66340
|
+
"use strict";
|
|
66341
|
+
init_founder_paid_badge();
|
|
66342
|
+
}
|
|
66343
|
+
});
|
|
66344
|
+
|
|
66190
66345
|
// bin/approved-claims-sync.js
|
|
66191
66346
|
var approved_claims_sync_exports = {};
|
|
66192
66347
|
__export(approved_claims_sync_exports, {
|
|
@@ -66589,6 +66744,20 @@ async function run28() {
|
|
|
66589
66744
|
founderPaid = computeFounderPaid2(index, (readCacheEntry2() ?? {}).founderPaid);
|
|
66590
66745
|
} catch {
|
|
66591
66746
|
}
|
|
66747
|
+
let founderPaidOsNotified;
|
|
66748
|
+
try {
|
|
66749
|
+
if (isFounderBountyNotifyEnabled()) {
|
|
66750
|
+
const { maybeNotifyFounderBounties: maybeNotifyFounderBounties2 } = await Promise.resolve().then(() => (init_founder_bounty_notify(), founder_bounty_notify_exports));
|
|
66751
|
+
const { readCacheEntry: readCacheEntry2 } = await Promise.resolve().then(() => (init_cache_store(), cache_store_exports));
|
|
66752
|
+
const result = maybeNotifyFounderBounties2({
|
|
66753
|
+
index,
|
|
66754
|
+
previous: (readCacheEntry2() ?? {}).founderPaidOsNotified,
|
|
66755
|
+
optedIn: true
|
|
66756
|
+
});
|
|
66757
|
+
founderPaidOsNotified = result.state;
|
|
66758
|
+
}
|
|
66759
|
+
} catch {
|
|
66760
|
+
}
|
|
66592
66761
|
let approvedClaims;
|
|
66593
66762
|
try {
|
|
66594
66763
|
const { syncApprovedClaims: syncApprovedClaims2 } = await Promise.resolve().then(() => (init_approved_claims_sync(), approved_claims_sync_exports));
|
|
@@ -66635,6 +66804,7 @@ async function run28() {
|
|
|
66635
66804
|
surfaceLead
|
|
66636
66805
|
};
|
|
66637
66806
|
if (founderPaid) cacheEntry.founderPaid = founderPaid;
|
|
66807
|
+
if (founderPaidOsNotified) cacheEntry.founderPaidOsNotified = founderPaidOsNotified;
|
|
66638
66808
|
if (approvedClaims) cacheEntry.approvedClaims = approvedClaims;
|
|
66639
66809
|
if (founderNotes) cacheEntry.founderNotes = founderNotes;
|
|
66640
66810
|
if (founderSurface) cacheEntry.founderSurface = founderSurface;
|
package/dist/bin/jpi-hub.js
CHANGED
|
@@ -11666,7 +11666,8 @@ var init_config = __esm({
|
|
|
11666
11666
|
lastFullFeedbackAt: null,
|
|
11667
11667
|
lastPulseAskAt: null,
|
|
11668
11668
|
pulseDisclosed: false,
|
|
11669
|
-
mix: "balanced"
|
|
11669
|
+
mix: "balanced",
|
|
11670
|
+
founderBountyNotify: false
|
|
11670
11671
|
};
|
|
11671
11672
|
}
|
|
11672
11673
|
});
|
package/dist/bin/jpi-inbox.js
CHANGED
package/dist/bin/jpi-jobs.js
CHANGED
|
@@ -11932,6 +11932,7 @@ __export(config_exports, {
|
|
|
11932
11932
|
getSurfaceMix: () => getSurfaceMix,
|
|
11933
11933
|
isBetaOptIn: () => isBetaOptIn,
|
|
11934
11934
|
isContributeEnabled: () => isContributeEnabled,
|
|
11935
|
+
isFounderBountyNotifyEnabled: () => isFounderBountyNotifyEnabled,
|
|
11935
11936
|
isInboundNudgeMuted: () => isInboundNudgeMuted,
|
|
11936
11937
|
isPeerConnectEnabled: () => isPeerConnectEnabled,
|
|
11937
11938
|
parseNudgeMode: () => parseNudgeMode,
|
|
@@ -12016,6 +12017,9 @@ function isContributeEnabled() {
|
|
|
12016
12017
|
function isBetaOptIn() {
|
|
12017
12018
|
return readConfig().betaOptIn === true;
|
|
12018
12019
|
}
|
|
12020
|
+
function isFounderBountyNotifyEnabled() {
|
|
12021
|
+
return readConfig().founderBountyNotify === true;
|
|
12022
|
+
}
|
|
12019
12023
|
var TERMINALHIRE_DIR5, CONFIG_FILE, DEFAULT_CONFIG;
|
|
12020
12024
|
var init_config = __esm({
|
|
12021
12025
|
"src/config.ts"() {
|
|
@@ -12037,7 +12041,8 @@ var init_config = __esm({
|
|
|
12037
12041
|
lastFullFeedbackAt: null,
|
|
12038
12042
|
lastPulseAskAt: null,
|
|
12039
12043
|
pulseDisclosed: false,
|
|
12040
|
-
mix: "balanced"
|
|
12044
|
+
mix: "balanced",
|
|
12045
|
+
founderBountyNotify: false
|
|
12041
12046
|
};
|
|
12042
12047
|
}
|
|
12043
12048
|
});
|
package/dist/bin/jpi-link.js
CHANGED
package/dist/bin/jpi-login.js
CHANGED
|
@@ -11277,7 +11277,8 @@ var init_config = __esm({
|
|
|
11277
11277
|
lastFullFeedbackAt: null,
|
|
11278
11278
|
lastPulseAskAt: null,
|
|
11279
11279
|
pulseDisclosed: false,
|
|
11280
|
-
mix: "balanced"
|
|
11280
|
+
mix: "balanced",
|
|
11281
|
+
founderBountyNotify: false
|
|
11281
11282
|
};
|
|
11282
11283
|
}
|
|
11283
11284
|
});
|
package/dist/bin/jpi-mcp-chat.js
CHANGED
package/dist/bin/jpi-mcp.js
CHANGED
|
@@ -52521,6 +52521,7 @@ __export(config_exports, {
|
|
|
52521
52521
|
getSurfaceMix: () => getSurfaceMix,
|
|
52522
52522
|
isBetaOptIn: () => isBetaOptIn,
|
|
52523
52523
|
isContributeEnabled: () => isContributeEnabled,
|
|
52524
|
+
isFounderBountyNotifyEnabled: () => isFounderBountyNotifyEnabled,
|
|
52524
52525
|
isInboundNudgeMuted: () => isInboundNudgeMuted,
|
|
52525
52526
|
isPeerConnectEnabled: () => isPeerConnectEnabled,
|
|
52526
52527
|
parseNudgeMode: () => parseNudgeMode,
|
|
@@ -52605,6 +52606,9 @@ function isContributeEnabled() {
|
|
|
52605
52606
|
function isBetaOptIn() {
|
|
52606
52607
|
return readConfig().betaOptIn === true;
|
|
52607
52608
|
}
|
|
52609
|
+
function isFounderBountyNotifyEnabled() {
|
|
52610
|
+
return readConfig().founderBountyNotify === true;
|
|
52611
|
+
}
|
|
52608
52612
|
var TERMINALHIRE_DIR12, CONFIG_FILE, DEFAULT_CONFIG;
|
|
52609
52613
|
var init_config = __esm({
|
|
52610
52614
|
"src/config.ts"() {
|
|
@@ -52626,7 +52630,8 @@ var init_config = __esm({
|
|
|
52626
52630
|
lastFullFeedbackAt: null,
|
|
52627
52631
|
lastPulseAskAt: null,
|
|
52628
52632
|
pulseDisclosed: false,
|
|
52629
|
-
mix: "balanced"
|
|
52633
|
+
mix: "balanced",
|
|
52634
|
+
founderBountyNotify: false
|
|
52630
52635
|
};
|
|
52631
52636
|
}
|
|
52632
52637
|
});
|
package/dist/bin/jpi-refresh.js
CHANGED
|
@@ -148,6 +148,7 @@ __export(config_exports, {
|
|
|
148
148
|
getSurfaceMix: () => getSurfaceMix,
|
|
149
149
|
isBetaOptIn: () => isBetaOptIn,
|
|
150
150
|
isContributeEnabled: () => isContributeEnabled,
|
|
151
|
+
isFounderBountyNotifyEnabled: () => isFounderBountyNotifyEnabled,
|
|
151
152
|
isInboundNudgeMuted: () => isInboundNudgeMuted,
|
|
152
153
|
isPeerConnectEnabled: () => isPeerConnectEnabled,
|
|
153
154
|
parseNudgeMode: () => parseNudgeMode,
|
|
@@ -232,6 +233,9 @@ function isContributeEnabled() {
|
|
|
232
233
|
function isBetaOptIn() {
|
|
233
234
|
return readConfig().betaOptIn === true;
|
|
234
235
|
}
|
|
236
|
+
function isFounderBountyNotifyEnabled() {
|
|
237
|
+
return readConfig().founderBountyNotify === true;
|
|
238
|
+
}
|
|
235
239
|
var TERMINALHIRE_DIR3, CONFIG_FILE, DEFAULT_CONFIG;
|
|
236
240
|
var init_config = __esm({
|
|
237
241
|
"src/config.ts"() {
|
|
@@ -253,7 +257,8 @@ var init_config = __esm({
|
|
|
253
257
|
lastFullFeedbackAt: null,
|
|
254
258
|
lastPulseAskAt: null,
|
|
255
259
|
pulseDisclosed: false,
|
|
256
|
-
mix: "balanced"
|
|
260
|
+
mix: "balanced",
|
|
261
|
+
founderBountyNotify: false
|
|
257
262
|
};
|
|
258
263
|
}
|
|
259
264
|
});
|
|
@@ -13121,6 +13126,113 @@ var init_founder_paid_badge = __esm({
|
|
|
13121
13126
|
}
|
|
13122
13127
|
});
|
|
13123
13128
|
|
|
13129
|
+
// bin/founder-bounty-notify.js
|
|
13130
|
+
var founder_bounty_notify_exports = {};
|
|
13131
|
+
__export(founder_bounty_notify_exports, {
|
|
13132
|
+
displayLocalNotification: () => displayLocalNotification,
|
|
13133
|
+
escapeAppleScriptString: () => escapeAppleScriptString,
|
|
13134
|
+
formatFounderBountyNotifyBody: () => formatFounderBountyNotifyBody,
|
|
13135
|
+
maybeNotifyFounderBounties: () => maybeNotifyFounderBounties,
|
|
13136
|
+
nextFounderBountyNotifyState: () => nextFounderBountyNotifyState
|
|
13137
|
+
});
|
|
13138
|
+
import { spawn } from "child_process";
|
|
13139
|
+
function nextFounderBountyNotifyState(index, previous) {
|
|
13140
|
+
const open = openPaidIds(index);
|
|
13141
|
+
const prior = previous && Array.isArray(previous.ids) ? previous.ids : null;
|
|
13142
|
+
if (prior === null) {
|
|
13143
|
+
return { ids: open, fire: [], seeded: true };
|
|
13144
|
+
}
|
|
13145
|
+
const seen = new Set(prior);
|
|
13146
|
+
const fire = open.filter((id) => !seen.has(id));
|
|
13147
|
+
const ids = [.../* @__PURE__ */ new Set([...prior.filter((id) => open.includes(id)), ...fire])].sort();
|
|
13148
|
+
return { ids, fire, seeded: false };
|
|
13149
|
+
}
|
|
13150
|
+
function formatFounderBountyNotifyBody(index, fireIds) {
|
|
13151
|
+
const jobs = index && index.jobs || [];
|
|
13152
|
+
const byId = /* @__PURE__ */ new Map();
|
|
13153
|
+
for (const j of jobs) {
|
|
13154
|
+
if (j && typeof j.id === "string") byId.set(j.id, j);
|
|
13155
|
+
}
|
|
13156
|
+
if (fireIds.length === 1) {
|
|
13157
|
+
const j = byId.get(fireIds[0]);
|
|
13158
|
+
const amount = j && j.bounty && typeof j.bounty.amountUSD === "number" ? j.bounty.amountUSD : null;
|
|
13159
|
+
const price = typeof amount === "number" && Number.isFinite(amount) && amount > 0 ? `$${Math.round(amount)} ` : "";
|
|
13160
|
+
return `${price}founder bounty available \u2014 run: terminalhire bounties`;
|
|
13161
|
+
}
|
|
13162
|
+
return `${fireIds.length} founder bounties available \u2014 run: terminalhire bounties`;
|
|
13163
|
+
}
|
|
13164
|
+
function escapeAppleScriptString(s) {
|
|
13165
|
+
return String(s).replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
13166
|
+
}
|
|
13167
|
+
function displayLocalNotification({
|
|
13168
|
+
title = "Terminalhire",
|
|
13169
|
+
body,
|
|
13170
|
+
platform = process.platform,
|
|
13171
|
+
spawnFn = spawn
|
|
13172
|
+
} = {}) {
|
|
13173
|
+
if (!body || typeof body !== "string") return false;
|
|
13174
|
+
try {
|
|
13175
|
+
if (platform === "darwin") {
|
|
13176
|
+
const t = escapeAppleScriptString(title);
|
|
13177
|
+
const b = escapeAppleScriptString(body);
|
|
13178
|
+
const child = spawnFn("osascript", ["-e", `display notification "${b}" with title "${t}"`], {
|
|
13179
|
+
detached: true,
|
|
13180
|
+
stdio: "ignore"
|
|
13181
|
+
});
|
|
13182
|
+
if (child && typeof child.unref === "function") child.unref();
|
|
13183
|
+
return true;
|
|
13184
|
+
}
|
|
13185
|
+
if (platform === "win32") {
|
|
13186
|
+
const safeTitle = String(title).replace(/'/g, "''");
|
|
13187
|
+
const safeBody = String(body).replace(/'/g, "''");
|
|
13188
|
+
const ps = `
|
|
13189
|
+
Add-Type -AssemblyName System.Windows.Forms
|
|
13190
|
+
$n = New-Object System.Windows.Forms.NotifyIcon
|
|
13191
|
+
$n.Icon = [System.Drawing.SystemIcons]::Information
|
|
13192
|
+
$n.Visible = $true
|
|
13193
|
+
$n.ShowBalloonTip(8000, '${safeTitle}', '${safeBody}', [System.Windows.Forms.ToolTipIcon]::Info)
|
|
13194
|
+
Start-Sleep -Seconds 9
|
|
13195
|
+
$n.Dispose()
|
|
13196
|
+
`.trim();
|
|
13197
|
+
const child = spawnFn("powershell.exe", ["-NoProfile", "-Command", ps], {
|
|
13198
|
+
detached: true,
|
|
13199
|
+
stdio: "ignore",
|
|
13200
|
+
windowsHide: true
|
|
13201
|
+
});
|
|
13202
|
+
if (child && typeof child.unref === "function") child.unref();
|
|
13203
|
+
return true;
|
|
13204
|
+
}
|
|
13205
|
+
return false;
|
|
13206
|
+
} catch {
|
|
13207
|
+
return false;
|
|
13208
|
+
}
|
|
13209
|
+
}
|
|
13210
|
+
function maybeNotifyFounderBounties({
|
|
13211
|
+
index,
|
|
13212
|
+
previous,
|
|
13213
|
+
optedIn,
|
|
13214
|
+
display = displayLocalNotification
|
|
13215
|
+
} = {}) {
|
|
13216
|
+
if (!optedIn) {
|
|
13217
|
+
const ids = previous && Array.isArray(previous.ids) ? [...previous.ids].sort() : [];
|
|
13218
|
+
return { state: { ids }, fired: [] };
|
|
13219
|
+
}
|
|
13220
|
+
const next = nextFounderBountyNotifyState(index, previous);
|
|
13221
|
+
if (next.fire.length > 0) {
|
|
13222
|
+
display({
|
|
13223
|
+
title: "Terminalhire",
|
|
13224
|
+
body: formatFounderBountyNotifyBody(index, next.fire)
|
|
13225
|
+
});
|
|
13226
|
+
}
|
|
13227
|
+
return { state: { ids: next.ids }, fired: next.fire };
|
|
13228
|
+
}
|
|
13229
|
+
var init_founder_bounty_notify = __esm({
|
|
13230
|
+
"bin/founder-bounty-notify.js"() {
|
|
13231
|
+
"use strict";
|
|
13232
|
+
init_founder_paid_badge();
|
|
13233
|
+
}
|
|
13234
|
+
});
|
|
13235
|
+
|
|
13124
13236
|
// bin/approved-claims-sync.js
|
|
13125
13237
|
var approved_claims_sync_exports = {};
|
|
13126
13238
|
__export(approved_claims_sync_exports, {
|
|
@@ -14071,6 +14183,20 @@ async function run() {
|
|
|
14071
14183
|
founderPaid = computeFounderPaid2(index, (readCacheEntry2() ?? {}).founderPaid);
|
|
14072
14184
|
} catch {
|
|
14073
14185
|
}
|
|
14186
|
+
let founderPaidOsNotified;
|
|
14187
|
+
try {
|
|
14188
|
+
if (isFounderBountyNotifyEnabled()) {
|
|
14189
|
+
const { maybeNotifyFounderBounties: maybeNotifyFounderBounties2 } = await Promise.resolve().then(() => (init_founder_bounty_notify(), founder_bounty_notify_exports));
|
|
14190
|
+
const { readCacheEntry: readCacheEntry2 } = await Promise.resolve().then(() => (init_cache_store(), cache_store_exports));
|
|
14191
|
+
const result = maybeNotifyFounderBounties2({
|
|
14192
|
+
index,
|
|
14193
|
+
previous: (readCacheEntry2() ?? {}).founderPaidOsNotified,
|
|
14194
|
+
optedIn: true
|
|
14195
|
+
});
|
|
14196
|
+
founderPaidOsNotified = result.state;
|
|
14197
|
+
}
|
|
14198
|
+
} catch {
|
|
14199
|
+
}
|
|
14074
14200
|
let approvedClaims;
|
|
14075
14201
|
try {
|
|
14076
14202
|
const { syncApprovedClaims: syncApprovedClaims2 } = await Promise.resolve().then(() => (init_approved_claims_sync(), approved_claims_sync_exports));
|
|
@@ -14117,6 +14243,7 @@ async function run() {
|
|
|
14117
14243
|
surfaceLead
|
|
14118
14244
|
};
|
|
14119
14245
|
if (founderPaid) cacheEntry.founderPaid = founderPaid;
|
|
14246
|
+
if (founderPaidOsNotified) cacheEntry.founderPaidOsNotified = founderPaidOsNotified;
|
|
14120
14247
|
if (approvedClaims) cacheEntry.approvedClaims = approvedClaims;
|
|
14121
14248
|
if (founderNotes) cacheEntry.founderNotes = founderNotes;
|
|
14122
14249
|
if (founderSurface) cacheEntry.founderSurface = founderSurface;
|
package/dist/bin/pulse-prompt.js
CHANGED
package/dist/src/config.js
CHANGED
|
@@ -68,7 +68,8 @@ var DEFAULT_CONFIG = {
|
|
|
68
68
|
lastFullFeedbackAt: null,
|
|
69
69
|
lastPulseAskAt: null,
|
|
70
70
|
pulseDisclosed: false,
|
|
71
|
-
mix: "balanced"
|
|
71
|
+
mix: "balanced",
|
|
72
|
+
founderBountyNotify: false
|
|
72
73
|
};
|
|
73
74
|
function readConfig() {
|
|
74
75
|
try {
|
|
@@ -143,12 +144,16 @@ function isContributeEnabled() {
|
|
|
143
144
|
function isBetaOptIn() {
|
|
144
145
|
return readConfig().betaOptIn === true;
|
|
145
146
|
}
|
|
147
|
+
function isFounderBountyNotifyEnabled() {
|
|
148
|
+
return readConfig().founderBountyNotify === true;
|
|
149
|
+
}
|
|
146
150
|
export {
|
|
147
151
|
getNudgeMode,
|
|
148
152
|
getSurfaceLeadOverride,
|
|
149
153
|
getSurfaceMix,
|
|
150
154
|
isBetaOptIn,
|
|
151
155
|
isContributeEnabled,
|
|
156
|
+
isFounderBountyNotifyEnabled,
|
|
152
157
|
isInboundNudgeMuted,
|
|
153
158
|
isPeerConnectEnabled,
|
|
154
159
|
parseNudgeMode,
|
package/dist/src/link.js
CHANGED
package/package.json
CHANGED