terminalhire 0.16.0 → 0.16.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/dist/bin/jpi-chat.js +18 -6
- package/dist/bin/jpi-dispatch.js +50 -8
- package/dist/bin/jpi-inbox.js +21 -9
- package/dist/bin/jpi-refresh.js +31 -2
- package/dist/bin/jpi-spinner.js +17 -1
- package/dist/bin/jpi-statusline.js +2 -2
- package/dist/bin/jpi.js +5 -5
- package/dist/bin/spinner.js +19 -1
- package/dist/src/config.js +4 -0
- package/package.json +1 -1
package/dist/bin/jpi-chat.js
CHANGED
|
@@ -5816,7 +5816,7 @@ async function runInboxTui(deps = {}) {
|
|
|
5816
5816
|
const sel = await runInboxPane({ input, output, ...paneDeps });
|
|
5817
5817
|
if (!sel || sel.action === "quit") break;
|
|
5818
5818
|
if (sel.action === "open" && sel.login) {
|
|
5819
|
-
await openChatPane({ login: sel.login, input, output });
|
|
5819
|
+
await openChatPane({ login: sel.login, input, output, backHint: "inbox" });
|
|
5820
5820
|
}
|
|
5821
5821
|
}
|
|
5822
5822
|
return { ok: true };
|
|
@@ -5994,7 +5994,7 @@ function formatPresence(presence, now = /* @__PURE__ */ new Date()) {
|
|
|
5994
5994
|
return "\u25D0 reachable";
|
|
5995
5995
|
}
|
|
5996
5996
|
function formatThread(state) {
|
|
5997
|
-
const { peerLogin, presence, self, messages, inputBuffer, banner } = state;
|
|
5997
|
+
const { peerLogin, presence, self, messages, inputBuffer, banner, backHint } = state;
|
|
5998
5998
|
const safePeer = sanitizeLine(peerLogin);
|
|
5999
5999
|
const status = formatPresence(presence);
|
|
6000
6000
|
const lines = [];
|
|
@@ -6022,7 +6022,9 @@ function formatThread(state) {
|
|
|
6022
6022
|
}
|
|
6023
6023
|
lines.push(" " + "\u2500".repeat(56));
|
|
6024
6024
|
lines.push(` > ${inputBuffer}`);
|
|
6025
|
-
lines.push(
|
|
6025
|
+
lines.push(
|
|
6026
|
+
backHint ? ` Esc back to ${sanitizeLine(backHint)} \xB7 Enter send \xB7 Ctrl-S safety number \xB7 /safety \xB7 /block \xB7 q quit` : " Enter send \xB7 Ctrl-S safety number \xB7 /safety \xB7 /block \xB7 q quit"
|
|
6027
|
+
);
|
|
6026
6028
|
return CLEAR2 + lines.join("\n") + "\n";
|
|
6027
6029
|
}
|
|
6028
6030
|
function mergeMessages(existing, incoming) {
|
|
@@ -6065,7 +6067,10 @@ async function runChatPane(opts = {}) {
|
|
|
6065
6067
|
pollIntervalMs = 1500,
|
|
6066
6068
|
setTimer = (fn, ms) => setInterval(fn, ms),
|
|
6067
6069
|
clearTimer = (t) => clearInterval(t),
|
|
6068
|
-
markRead = defaultMarkThreadRead
|
|
6070
|
+
markRead = defaultMarkThreadRead,
|
|
6071
|
+
// Where Esc returns to, when opened from a parent surface (the inbox TUI
|
|
6072
|
+
// passes 'inbox'). Copy-only — the caller's loop does the actual returning.
|
|
6073
|
+
backHint = null
|
|
6069
6074
|
} = opts;
|
|
6070
6075
|
const target = String(login ?? "").replace(/^@/, "").trim();
|
|
6071
6076
|
if (!target) {
|
|
@@ -6195,7 +6200,8 @@ async function runChatPane(opts = {}) {
|
|
|
6195
6200
|
self: { login: selfLogin, expired: selfExpired, shareActivity: selfShareActivity },
|
|
6196
6201
|
messages,
|
|
6197
6202
|
inputBuffer,
|
|
6198
|
-
banner
|
|
6203
|
+
banner,
|
|
6204
|
+
backHint
|
|
6199
6205
|
})
|
|
6200
6206
|
);
|
|
6201
6207
|
}
|
|
@@ -6388,6 +6394,11 @@ async function runChatPane(opts = {}) {
|
|
|
6388
6394
|
function onData(chunk) {
|
|
6389
6395
|
if (cleaned) return;
|
|
6390
6396
|
const s = chunk.toString("utf8");
|
|
6397
|
+
if (s === KEY_ESC2) {
|
|
6398
|
+
finish("back");
|
|
6399
|
+
return;
|
|
6400
|
+
}
|
|
6401
|
+
if (s.charCodeAt(0) === 27) return;
|
|
6391
6402
|
for (const ch of s) {
|
|
6392
6403
|
if (ch === KEY_CTRL_C2) {
|
|
6393
6404
|
finish("sigint");
|
|
@@ -6629,7 +6640,7 @@ async function run2() {
|
|
|
6629
6640
|
process.exit(1);
|
|
6630
6641
|
}
|
|
6631
6642
|
}
|
|
6632
|
-
var CHAT_BASE3, GH_SESSION_COOKIE4, HIDE_CURSOR2, SHOW_CURSOR2, ENTER_ALT2, EXIT_ALT2, CLEAR2, KEY_CTRL_C2, KEY_CTRL_S, KEY_ENTER_A2, KEY_ENTER_B2, KEY_BACKSPACE_A2, KEY_BACKSPACE_B2, MAX_INPUT_LEN, ANSI_CSI, ANSI_OSC, ANSI_OTHER, C0_C1_DEL, CHAT_DISCLOSURE, CHAT_AT_REST, CHAT_CODE_OF_CONDUCT, CHAT_MIN_AGE, DEPOSIT_CTA, ACTIVE_WINDOW_MS;
|
|
6643
|
+
var CHAT_BASE3, GH_SESSION_COOKIE4, HIDE_CURSOR2, SHOW_CURSOR2, ENTER_ALT2, EXIT_ALT2, CLEAR2, KEY_CTRL_C2, KEY_ESC2, KEY_CTRL_S, KEY_ENTER_A2, KEY_ENTER_B2, KEY_BACKSPACE_A2, KEY_BACKSPACE_B2, MAX_INPUT_LEN, ANSI_CSI, ANSI_OSC, ANSI_OTHER, C0_C1_DEL, CHAT_DISCLOSURE, CHAT_AT_REST, CHAT_CODE_OF_CONDUCT, CHAT_MIN_AGE, DEPOSIT_CTA, ACTIVE_WINDOW_MS;
|
|
6633
6644
|
var init_jpi_chat = __esm({
|
|
6634
6645
|
"bin/jpi-chat.js"() {
|
|
6635
6646
|
init_chat_client();
|
|
@@ -6643,6 +6654,7 @@ var init_jpi_chat = __esm({
|
|
|
6643
6654
|
EXIT_ALT2 = "\x1B[?1049l";
|
|
6644
6655
|
CLEAR2 = "\x1B[2J\x1B[H";
|
|
6645
6656
|
KEY_CTRL_C2 = "";
|
|
6657
|
+
KEY_ESC2 = "\x1B";
|
|
6646
6658
|
KEY_CTRL_S = "";
|
|
6647
6659
|
KEY_ENTER_A2 = "\r";
|
|
6648
6660
|
KEY_ENTER_B2 = "\n";
|
package/dist/bin/jpi-dispatch.js
CHANGED
|
@@ -76,6 +76,7 @@ var config_exports = {};
|
|
|
76
76
|
__export(config_exports, {
|
|
77
77
|
getNudgeMode: () => getNudgeMode,
|
|
78
78
|
isContributeEnabled: () => isContributeEnabled,
|
|
79
|
+
isContributePrompted: () => isContributePrompted,
|
|
79
80
|
isInboundNudgeMuted: () => isInboundNudgeMuted,
|
|
80
81
|
isPeerConnectEnabled: () => isPeerConnectEnabled,
|
|
81
82
|
parseNudgeMode: () => parseNudgeMode,
|
|
@@ -128,6 +129,9 @@ function isInboundNudgeMuted() {
|
|
|
128
129
|
function isContributeEnabled() {
|
|
129
130
|
return readConfig().contributeEnabled === true;
|
|
130
131
|
}
|
|
132
|
+
function isContributePrompted() {
|
|
133
|
+
return readConfig().contributePrompted === true;
|
|
134
|
+
}
|
|
131
135
|
var TERMINALHIRE_DIR, CONFIG_FILE, DEFAULT_CONFIG;
|
|
132
136
|
var init_config = __esm({
|
|
133
137
|
"src/config.ts"() {
|
|
@@ -12026,7 +12030,7 @@ async function runInboxTui(deps = {}) {
|
|
|
12026
12030
|
const sel = await runInboxPane({ input, output, ...paneDeps });
|
|
12027
12031
|
if (!sel || sel.action === "quit") break;
|
|
12028
12032
|
if (sel.action === "open" && sel.login) {
|
|
12029
|
-
await openChatPane({ login: sel.login, input, output });
|
|
12033
|
+
await openChatPane({ login: sel.login, input, output, backHint: "inbox" });
|
|
12030
12034
|
}
|
|
12031
12035
|
}
|
|
12032
12036
|
return { ok: true };
|
|
@@ -12224,7 +12228,7 @@ function formatPresence(presence, now = /* @__PURE__ */ new Date()) {
|
|
|
12224
12228
|
return "\u25D0 reachable";
|
|
12225
12229
|
}
|
|
12226
12230
|
function formatThread(state) {
|
|
12227
|
-
const { peerLogin, presence, self, messages, inputBuffer, banner } = state;
|
|
12231
|
+
const { peerLogin, presence, self, messages, inputBuffer, banner, backHint } = state;
|
|
12228
12232
|
const safePeer = sanitizeLine(peerLogin);
|
|
12229
12233
|
const status = formatPresence(presence);
|
|
12230
12234
|
const lines = [];
|
|
@@ -12252,7 +12256,9 @@ function formatThread(state) {
|
|
|
12252
12256
|
}
|
|
12253
12257
|
lines.push(" " + "\u2500".repeat(56));
|
|
12254
12258
|
lines.push(` > ${inputBuffer}`);
|
|
12255
|
-
lines.push(
|
|
12259
|
+
lines.push(
|
|
12260
|
+
backHint ? ` Esc back to ${sanitizeLine(backHint)} \xB7 Enter send \xB7 Ctrl-S safety number \xB7 /safety \xB7 /block \xB7 q quit` : " Enter send \xB7 Ctrl-S safety number \xB7 /safety \xB7 /block \xB7 q quit"
|
|
12261
|
+
);
|
|
12256
12262
|
return CLEAR2 + lines.join("\n") + "\n";
|
|
12257
12263
|
}
|
|
12258
12264
|
function mergeMessages(existing, incoming) {
|
|
@@ -12295,7 +12301,10 @@ async function runChatPane(opts = {}) {
|
|
|
12295
12301
|
pollIntervalMs = 1500,
|
|
12296
12302
|
setTimer = (fn, ms) => setInterval(fn, ms),
|
|
12297
12303
|
clearTimer = (t) => clearInterval(t),
|
|
12298
|
-
markRead = defaultMarkThreadRead
|
|
12304
|
+
markRead = defaultMarkThreadRead,
|
|
12305
|
+
// Where Esc returns to, when opened from a parent surface (the inbox TUI
|
|
12306
|
+
// passes 'inbox'). Copy-only — the caller's loop does the actual returning.
|
|
12307
|
+
backHint = null
|
|
12299
12308
|
} = opts;
|
|
12300
12309
|
const target = String(login ?? "").replace(/^@/, "").trim();
|
|
12301
12310
|
if (!target) {
|
|
@@ -12425,7 +12434,8 @@ async function runChatPane(opts = {}) {
|
|
|
12425
12434
|
self: { login: selfLogin, expired: selfExpired, shareActivity: selfShareActivity },
|
|
12426
12435
|
messages,
|
|
12427
12436
|
inputBuffer,
|
|
12428
|
-
banner
|
|
12437
|
+
banner,
|
|
12438
|
+
backHint
|
|
12429
12439
|
})
|
|
12430
12440
|
);
|
|
12431
12441
|
}
|
|
@@ -12618,6 +12628,11 @@ async function runChatPane(opts = {}) {
|
|
|
12618
12628
|
function onData(chunk) {
|
|
12619
12629
|
if (cleaned) return;
|
|
12620
12630
|
const s = chunk.toString("utf8");
|
|
12631
|
+
if (s === KEY_ESC2) {
|
|
12632
|
+
finish("back");
|
|
12633
|
+
return;
|
|
12634
|
+
}
|
|
12635
|
+
if (s.charCodeAt(0) === 27) return;
|
|
12621
12636
|
for (const ch of s) {
|
|
12622
12637
|
if (ch === KEY_CTRL_C2) {
|
|
12623
12638
|
finish("sigint");
|
|
@@ -12859,7 +12874,7 @@ async function run11() {
|
|
|
12859
12874
|
process.exit(1);
|
|
12860
12875
|
}
|
|
12861
12876
|
}
|
|
12862
|
-
var CHAT_BASE3, GH_SESSION_COOKIE5, HIDE_CURSOR2, SHOW_CURSOR2, ENTER_ALT2, EXIT_ALT2, CLEAR2, KEY_CTRL_C2, KEY_CTRL_S, KEY_ENTER_A2, KEY_ENTER_B2, KEY_BACKSPACE_A2, KEY_BACKSPACE_B2, MAX_INPUT_LEN, ANSI_CSI, ANSI_OSC, ANSI_OTHER, C0_C1_DEL, CHAT_DISCLOSURE, CHAT_AT_REST, CHAT_CODE_OF_CONDUCT, CHAT_MIN_AGE, DEPOSIT_CTA, ACTIVE_WINDOW_MS;
|
|
12877
|
+
var CHAT_BASE3, GH_SESSION_COOKIE5, HIDE_CURSOR2, SHOW_CURSOR2, ENTER_ALT2, EXIT_ALT2, CLEAR2, KEY_CTRL_C2, KEY_ESC2, KEY_CTRL_S, KEY_ENTER_A2, KEY_ENTER_B2, KEY_BACKSPACE_A2, KEY_BACKSPACE_B2, MAX_INPUT_LEN, ANSI_CSI, ANSI_OSC, ANSI_OTHER, C0_C1_DEL, CHAT_DISCLOSURE, CHAT_AT_REST, CHAT_CODE_OF_CONDUCT, CHAT_MIN_AGE, DEPOSIT_CTA, ACTIVE_WINDOW_MS;
|
|
12863
12878
|
var init_jpi_chat = __esm({
|
|
12864
12879
|
"bin/jpi-chat.js"() {
|
|
12865
12880
|
"use strict";
|
|
@@ -12874,6 +12889,7 @@ var init_jpi_chat = __esm({
|
|
|
12874
12889
|
EXIT_ALT2 = "\x1B[?1049l";
|
|
12875
12890
|
CLEAR2 = "\x1B[2J\x1B[H";
|
|
12876
12891
|
KEY_CTRL_C2 = "";
|
|
12892
|
+
KEY_ESC2 = "\x1B";
|
|
12877
12893
|
KEY_CTRL_S = "";
|
|
12878
12894
|
KEY_ENTER_A2 = "\r";
|
|
12879
12895
|
KEY_ENTER_B2 = "\n";
|
|
@@ -13994,17 +14010,32 @@ function buildIncomingIntroLine(incomingPending) {
|
|
|
13994
14010
|
if (n < 1) return null;
|
|
13995
14011
|
return n === 1 ? `\u2198 someone wants to connect \xB7 terminalhire intro --list` : `\u2198 ${n} people want to connect \xB7 terminalhire intro --list`;
|
|
13996
14012
|
}
|
|
14013
|
+
function buildContributeNudgeLine(contributeNudge) {
|
|
14014
|
+
const n = contributeNudge && typeof contributeNudge.count === "number" ? contributeNudge.count : 0;
|
|
14015
|
+
if (n < 1) return null;
|
|
14016
|
+
return n === 1 ? "\u2726 an open-source issue that counts toward your r\xE9sum\xE9 \xB7 terminalhire contribute" : `\u2726 ${n} open-source issues that count toward your r\xE9sum\xE9 \xB7 terminalhire contribute`;
|
|
14017
|
+
}
|
|
13997
14018
|
function buildSessionStaleLine(sessionStale) {
|
|
13998
14019
|
return sessionStale === true ? "\u26A0 terminalhire: linked session expired \u2014 run: terminalhire login" : null;
|
|
13999
14020
|
}
|
|
14000
14021
|
function buildSpinnerPool(topMatches, _max = 6, opts = {}) {
|
|
14001
|
-
const {
|
|
14022
|
+
const {
|
|
14023
|
+
sessionTags,
|
|
14024
|
+
frequency = "always",
|
|
14025
|
+
topPeers,
|
|
14026
|
+
incomingPending,
|
|
14027
|
+
sessionStale,
|
|
14028
|
+
contributeNudge,
|
|
14029
|
+
seenHistory
|
|
14030
|
+
} = opts;
|
|
14002
14031
|
const staleLine = buildSessionStaleLine(sessionStale);
|
|
14003
14032
|
const withStale = (pool2) => staleLine ? [staleLine, ...pool2] : pool2;
|
|
14004
14033
|
const introLine = buildIncomingIntroLine(incomingPending);
|
|
14034
|
+
const contributeLine = buildContributeNudgeLine(contributeNudge);
|
|
14005
14035
|
const ranked = filterFreshMatches(rankBySessionTags(topMatches, sessionTags), seenHistory);
|
|
14006
14036
|
if (!Array.isArray(ranked) || ranked.length === 0) {
|
|
14007
14037
|
if (introLine) return withStale([introLine]);
|
|
14038
|
+
if (contributeLine) return withStale([contributeLine]);
|
|
14008
14039
|
const peerLine = buildPeerLine(topPeers);
|
|
14009
14040
|
return withStale(peerLine ? [peerLine] : []);
|
|
14010
14041
|
}
|
|
@@ -14012,6 +14043,7 @@ function buildSpinnerPool(topMatches, _max = 6, opts = {}) {
|
|
|
14012
14043
|
const cap = Math.max(1, verbCountForFrequency(frequency, headers.length));
|
|
14013
14044
|
const pool = [...headers.slice(0, cap), ctaVerb()];
|
|
14014
14045
|
if (introLine) pool.push(introLine);
|
|
14046
|
+
if (contributeLine) pool.push(contributeLine);
|
|
14015
14047
|
return withStale(pool);
|
|
14016
14048
|
}
|
|
14017
14049
|
var VERB_INTROS;
|
|
@@ -14146,6 +14178,7 @@ function renderRefreshSurface(topMatches, sc, opts = {}) {
|
|
|
14146
14178
|
topPeers: opts.topPeers,
|
|
14147
14179
|
incomingPending: opts.incomingPending,
|
|
14148
14180
|
sessionStale: opts.sessionStale,
|
|
14181
|
+
contributeNudge: opts.contributeNudge,
|
|
14149
14182
|
seenHistory
|
|
14150
14183
|
});
|
|
14151
14184
|
if (verbs.length > 0) applySpinnerVerbs(verbs, sc.mode);
|
|
@@ -14176,6 +14209,7 @@ __export(spinner_exports, {
|
|
|
14176
14209
|
applySpinnerTips: () => applySpinnerTips,
|
|
14177
14210
|
applySpinnerVerbs: () => applySpinnerVerbs,
|
|
14178
14211
|
buildContextVerbs: () => buildContextVerbs,
|
|
14212
|
+
buildContributeNudgeLine: () => buildContributeNudgeLine,
|
|
14179
14213
|
buildIncomingIntroLine: () => buildIncomingIntroLine,
|
|
14180
14214
|
buildPeerLine: () => buildPeerLine,
|
|
14181
14215
|
buildSessionStaleLine: () => buildSessionStaleLine,
|
|
@@ -14207,6 +14241,7 @@ var init_spinner = __esm({
|
|
|
14207
14241
|
init_spinner_verbs();
|
|
14208
14242
|
init_spinner_verbs();
|
|
14209
14243
|
init_spinner_verbs();
|
|
14244
|
+
init_spinner_verbs();
|
|
14210
14245
|
init_spinner_select();
|
|
14211
14246
|
init_spinner_select();
|
|
14212
14247
|
init_spinner_select();
|
|
@@ -15002,6 +15037,7 @@ async function run20() {
|
|
|
15002
15037
|
}
|
|
15003
15038
|
const jobs = index?.jobs ?? [];
|
|
15004
15039
|
const contribute = isContributeEnabled() && Array.isArray(index?.contribute) ? index.contribute : [];
|
|
15040
|
+
const contributeNudge = !isContributeEnabled() && !isContributePrompted() && Array.isArray(index?.contribute) && index.contribute.length > 0 ? { count: index.contribute.length } : null;
|
|
15005
15041
|
let matchCount = 0;
|
|
15006
15042
|
let topMatches = [];
|
|
15007
15043
|
let widenReserve = [];
|
|
@@ -15152,7 +15188,12 @@ async function run20() {
|
|
|
15152
15188
|
topPeers,
|
|
15153
15189
|
incomingPending,
|
|
15154
15190
|
unreadChat,
|
|
15155
|
-
sessionStale
|
|
15191
|
+
sessionStale,
|
|
15192
|
+
// In-process-only despite being persisted: the render pass receives it as
|
|
15193
|
+
// a function argument below. A future cache READER must not gate on this
|
|
15194
|
+
// field without re-checking isContributeEnabled/isContributePrompted at
|
|
15195
|
+
// read time — the persisted copy can be stale relative to the answer.
|
|
15196
|
+
contributeNudge
|
|
15156
15197
|
};
|
|
15157
15198
|
writeFileSync20(INDEX_CACHE_FILE7, JSON.stringify(cacheEntry), "utf8");
|
|
15158
15199
|
try {
|
|
@@ -15182,6 +15223,7 @@ async function run20() {
|
|
|
15182
15223
|
topPeers,
|
|
15183
15224
|
incomingPending,
|
|
15184
15225
|
sessionStale,
|
|
15226
|
+
contributeNudge,
|
|
15185
15227
|
baseUrl: API_URL7,
|
|
15186
15228
|
seenHistory,
|
|
15187
15229
|
widen
|
package/dist/bin/jpi-inbox.js
CHANGED
|
@@ -5058,7 +5058,7 @@ function formatPresence(presence, now = /* @__PURE__ */ new Date()) {
|
|
|
5058
5058
|
return "\u25D0 reachable";
|
|
5059
5059
|
}
|
|
5060
5060
|
function formatThread(state) {
|
|
5061
|
-
const { peerLogin, presence, self, messages, inputBuffer, banner } = state;
|
|
5061
|
+
const { peerLogin, presence, self, messages, inputBuffer, banner, backHint } = state;
|
|
5062
5062
|
const safePeer = sanitizeLine(peerLogin);
|
|
5063
5063
|
const status = formatPresence(presence);
|
|
5064
5064
|
const lines = [];
|
|
@@ -5086,7 +5086,9 @@ function formatThread(state) {
|
|
|
5086
5086
|
}
|
|
5087
5087
|
lines.push(" " + "\u2500".repeat(56));
|
|
5088
5088
|
lines.push(` > ${inputBuffer}`);
|
|
5089
|
-
lines.push(
|
|
5089
|
+
lines.push(
|
|
5090
|
+
backHint ? ` Esc back to ${sanitizeLine(backHint)} \xB7 Enter send \xB7 Ctrl-S safety number \xB7 /safety \xB7 /block \xB7 q quit` : " Enter send \xB7 Ctrl-S safety number \xB7 /safety \xB7 /block \xB7 q quit"
|
|
5091
|
+
);
|
|
5090
5092
|
return CLEAR + lines.join("\n") + "\n";
|
|
5091
5093
|
}
|
|
5092
5094
|
function mergeMessages(existing, incoming) {
|
|
@@ -5129,7 +5131,10 @@ async function runChatPane(opts = {}) {
|
|
|
5129
5131
|
pollIntervalMs = 1500,
|
|
5130
5132
|
setTimer = (fn, ms) => setInterval(fn, ms),
|
|
5131
5133
|
clearTimer = (t) => clearInterval(t),
|
|
5132
|
-
markRead = defaultMarkThreadRead
|
|
5134
|
+
markRead = defaultMarkThreadRead,
|
|
5135
|
+
// Where Esc returns to, when opened from a parent surface (the inbox TUI
|
|
5136
|
+
// passes 'inbox'). Copy-only — the caller's loop does the actual returning.
|
|
5137
|
+
backHint = null
|
|
5133
5138
|
} = opts;
|
|
5134
5139
|
const target = String(login ?? "").replace(/^@/, "").trim();
|
|
5135
5140
|
if (!target) {
|
|
@@ -5259,7 +5264,8 @@ async function runChatPane(opts = {}) {
|
|
|
5259
5264
|
self: { login: selfLogin, expired: selfExpired, shareActivity: selfShareActivity },
|
|
5260
5265
|
messages,
|
|
5261
5266
|
inputBuffer,
|
|
5262
|
-
banner
|
|
5267
|
+
banner,
|
|
5268
|
+
backHint
|
|
5263
5269
|
})
|
|
5264
5270
|
);
|
|
5265
5271
|
}
|
|
@@ -5452,6 +5458,11 @@ async function runChatPane(opts = {}) {
|
|
|
5452
5458
|
function onData(chunk) {
|
|
5453
5459
|
if (cleaned) return;
|
|
5454
5460
|
const s = chunk.toString("utf8");
|
|
5461
|
+
if (s === KEY_ESC) {
|
|
5462
|
+
finish("back");
|
|
5463
|
+
return;
|
|
5464
|
+
}
|
|
5465
|
+
if (s.charCodeAt(0) === 27) return;
|
|
5455
5466
|
for (const ch of s) {
|
|
5456
5467
|
if (ch === KEY_CTRL_C) {
|
|
5457
5468
|
finish("sigint");
|
|
@@ -5523,7 +5534,7 @@ async function runChatPane(opts = {}) {
|
|
|
5523
5534
|
}
|
|
5524
5535
|
});
|
|
5525
5536
|
}
|
|
5526
|
-
var CHAT_BASE3, GH_SESSION_COOKIE3, HIDE_CURSOR, SHOW_CURSOR, ENTER_ALT, EXIT_ALT, CLEAR, KEY_CTRL_C, KEY_CTRL_S, KEY_ENTER_A, KEY_ENTER_B, KEY_BACKSPACE_A, KEY_BACKSPACE_B, MAX_INPUT_LEN, ANSI_CSI, ANSI_OSC, ANSI_OTHER, C0_C1_DEL, CHAT_DISCLOSURE, CHAT_AT_REST, CHAT_CODE_OF_CONDUCT, CHAT_MIN_AGE, DEPOSIT_CTA, ACTIVE_WINDOW_MS;
|
|
5537
|
+
var CHAT_BASE3, GH_SESSION_COOKIE3, HIDE_CURSOR, SHOW_CURSOR, ENTER_ALT, EXIT_ALT, CLEAR, KEY_CTRL_C, KEY_ESC, KEY_CTRL_S, KEY_ENTER_A, KEY_ENTER_B, KEY_BACKSPACE_A, KEY_BACKSPACE_B, MAX_INPUT_LEN, ANSI_CSI, ANSI_OSC, ANSI_OTHER, C0_C1_DEL, CHAT_DISCLOSURE, CHAT_AT_REST, CHAT_CODE_OF_CONDUCT, CHAT_MIN_AGE, DEPOSIT_CTA, ACTIVE_WINDOW_MS;
|
|
5527
5538
|
var init_jpi_chat = __esm({
|
|
5528
5539
|
"bin/jpi-chat.js"() {
|
|
5529
5540
|
"use strict";
|
|
@@ -5538,6 +5549,7 @@ var init_jpi_chat = __esm({
|
|
|
5538
5549
|
EXIT_ALT = "\x1B[?1049l";
|
|
5539
5550
|
CLEAR = "\x1B[2J\x1B[H";
|
|
5540
5551
|
KEY_CTRL_C = "";
|
|
5552
|
+
KEY_ESC = "\x1B";
|
|
5541
5553
|
KEY_CTRL_S = "";
|
|
5542
5554
|
KEY_ENTER_A = "\r";
|
|
5543
5555
|
KEY_ENTER_B = "\n";
|
|
@@ -6308,7 +6320,7 @@ async function runInboxPane(opts = {}) {
|
|
|
6308
6320
|
finish({ action: "quit" });
|
|
6309
6321
|
return;
|
|
6310
6322
|
}
|
|
6311
|
-
if (s ===
|
|
6323
|
+
if (s === KEY_ESC2) {
|
|
6312
6324
|
if (mode === "input" || mode === "confirm") cancelMode();
|
|
6313
6325
|
else finish({ action: "quit" });
|
|
6314
6326
|
return;
|
|
@@ -6433,7 +6445,7 @@ async function runInboxTui(deps = {}) {
|
|
|
6433
6445
|
const sel = await runInboxPane({ input, output, ...paneDeps });
|
|
6434
6446
|
if (!sel || sel.action === "quit") break;
|
|
6435
6447
|
if (sel.action === "open" && sel.login) {
|
|
6436
|
-
await openChatPane({ login: sel.login, input, output });
|
|
6448
|
+
await openChatPane({ login: sel.login, input, output, backHint: "inbox" });
|
|
6437
6449
|
}
|
|
6438
6450
|
}
|
|
6439
6451
|
return { ok: true };
|
|
@@ -6455,7 +6467,7 @@ async function run(opts = {}) {
|
|
|
6455
6467
|
await mod2.runInbox({});
|
|
6456
6468
|
}
|
|
6457
6469
|
}
|
|
6458
|
-
var HIDE_CURSOR2, SHOW_CURSOR2, ENTER_ALT2, EXIT_ALT2, CLEAR2, INVERSE, RESET, BOLD, BOLD_OFF, KEY_CTRL_C2,
|
|
6470
|
+
var HIDE_CURSOR2, SHOW_CURSOR2, ENTER_ALT2, EXIT_ALT2, CLEAR2, INVERSE, RESET, BOLD, BOLD_OFF, KEY_CTRL_C2, KEY_ESC2, KEY_UP, KEY_DOWN, KEY_ENTER_A2, KEY_ENTER_B2, KEY_BACKSPACE_A2, KEY_BACKSPACE_B2, MAX_CONTACT_LEN, DEFAULT_REFRESH_MS;
|
|
6459
6471
|
var init_jpi_inbox = __esm({
|
|
6460
6472
|
"bin/jpi-inbox.js"() {
|
|
6461
6473
|
init_chat_client();
|
|
@@ -6471,7 +6483,7 @@ var init_jpi_inbox = __esm({
|
|
|
6471
6483
|
BOLD = "\x1B[1m";
|
|
6472
6484
|
BOLD_OFF = "\x1B[22m";
|
|
6473
6485
|
KEY_CTRL_C2 = "";
|
|
6474
|
-
|
|
6486
|
+
KEY_ESC2 = "\x1B";
|
|
6475
6487
|
KEY_UP = "\x1B[A";
|
|
6476
6488
|
KEY_DOWN = "\x1B[B";
|
|
6477
6489
|
KEY_ENTER_A2 = "\r";
|
package/dist/bin/jpi-refresh.js
CHANGED
|
@@ -7319,17 +7319,32 @@ function buildIncomingIntroLine(incomingPending) {
|
|
|
7319
7319
|
if (n < 1) return null;
|
|
7320
7320
|
return n === 1 ? `\u2198 someone wants to connect \xB7 terminalhire intro --list` : `\u2198 ${n} people want to connect \xB7 terminalhire intro --list`;
|
|
7321
7321
|
}
|
|
7322
|
+
function buildContributeNudgeLine(contributeNudge) {
|
|
7323
|
+
const n = contributeNudge && typeof contributeNudge.count === "number" ? contributeNudge.count : 0;
|
|
7324
|
+
if (n < 1) return null;
|
|
7325
|
+
return n === 1 ? "\u2726 an open-source issue that counts toward your r\xE9sum\xE9 \xB7 terminalhire contribute" : `\u2726 ${n} open-source issues that count toward your r\xE9sum\xE9 \xB7 terminalhire contribute`;
|
|
7326
|
+
}
|
|
7322
7327
|
function buildSessionStaleLine(sessionStale) {
|
|
7323
7328
|
return sessionStale === true ? "\u26A0 terminalhire: linked session expired \u2014 run: terminalhire login" : null;
|
|
7324
7329
|
}
|
|
7325
7330
|
function buildSpinnerPool(topMatches, _max = 6, opts = {}) {
|
|
7326
|
-
const {
|
|
7331
|
+
const {
|
|
7332
|
+
sessionTags,
|
|
7333
|
+
frequency = "always",
|
|
7334
|
+
topPeers,
|
|
7335
|
+
incomingPending,
|
|
7336
|
+
sessionStale,
|
|
7337
|
+
contributeNudge,
|
|
7338
|
+
seenHistory
|
|
7339
|
+
} = opts;
|
|
7327
7340
|
const staleLine = buildSessionStaleLine(sessionStale);
|
|
7328
7341
|
const withStale = (pool2) => staleLine ? [staleLine, ...pool2] : pool2;
|
|
7329
7342
|
const introLine = buildIncomingIntroLine(incomingPending);
|
|
7343
|
+
const contributeLine = buildContributeNudgeLine(contributeNudge);
|
|
7330
7344
|
const ranked = filterFreshMatches(rankBySessionTags(topMatches, sessionTags), seenHistory);
|
|
7331
7345
|
if (!Array.isArray(ranked) || ranked.length === 0) {
|
|
7332
7346
|
if (introLine) return withStale([introLine]);
|
|
7347
|
+
if (contributeLine) return withStale([contributeLine]);
|
|
7333
7348
|
const peerLine = buildPeerLine(topPeers);
|
|
7334
7349
|
return withStale(peerLine ? [peerLine] : []);
|
|
7335
7350
|
}
|
|
@@ -7337,6 +7352,7 @@ function buildSpinnerPool(topMatches, _max = 6, opts = {}) {
|
|
|
7337
7352
|
const cap = Math.max(1, verbCountForFrequency(frequency, headers.length));
|
|
7338
7353
|
const pool = [...headers.slice(0, cap), ctaVerb()];
|
|
7339
7354
|
if (introLine) pool.push(introLine);
|
|
7355
|
+
if (contributeLine) pool.push(contributeLine);
|
|
7340
7356
|
return withStale(pool);
|
|
7341
7357
|
}
|
|
7342
7358
|
var VERB_INTROS;
|
|
@@ -7471,6 +7487,7 @@ function renderRefreshSurface(topMatches, sc, opts = {}) {
|
|
|
7471
7487
|
topPeers: opts.topPeers,
|
|
7472
7488
|
incomingPending: opts.incomingPending,
|
|
7473
7489
|
sessionStale: opts.sessionStale,
|
|
7490
|
+
contributeNudge: opts.contributeNudge,
|
|
7474
7491
|
seenHistory
|
|
7475
7492
|
});
|
|
7476
7493
|
if (verbs.length > 0) applySpinnerVerbs(verbs, sc.mode);
|
|
@@ -7501,6 +7518,7 @@ __export(spinner_exports, {
|
|
|
7501
7518
|
applySpinnerTips: () => applySpinnerTips,
|
|
7502
7519
|
applySpinnerVerbs: () => applySpinnerVerbs,
|
|
7503
7520
|
buildContextVerbs: () => buildContextVerbs,
|
|
7521
|
+
buildContributeNudgeLine: () => buildContributeNudgeLine,
|
|
7504
7522
|
buildIncomingIntroLine: () => buildIncomingIntroLine,
|
|
7505
7523
|
buildPeerLine: () => buildPeerLine,
|
|
7506
7524
|
buildSessionStaleLine: () => buildSessionStaleLine,
|
|
@@ -7532,6 +7550,7 @@ var init_spinner = __esm({
|
|
|
7532
7550
|
init_spinner_verbs();
|
|
7533
7551
|
init_spinner_verbs();
|
|
7534
7552
|
init_spinner_verbs();
|
|
7553
|
+
init_spinner_verbs();
|
|
7535
7554
|
init_spinner_select();
|
|
7536
7555
|
init_spinner_select();
|
|
7537
7556
|
init_spinner_select();
|
|
@@ -7742,6 +7761,9 @@ function isInboundNudgeMuted() {
|
|
|
7742
7761
|
function isContributeEnabled() {
|
|
7743
7762
|
return readConfig().contributeEnabled === true;
|
|
7744
7763
|
}
|
|
7764
|
+
function isContributePrompted() {
|
|
7765
|
+
return readConfig().contributePrompted === true;
|
|
7766
|
+
}
|
|
7745
7767
|
|
|
7746
7768
|
// src/web-session.ts
|
|
7747
7769
|
import {
|
|
@@ -7806,6 +7828,7 @@ async function run() {
|
|
|
7806
7828
|
}
|
|
7807
7829
|
const jobs = index?.jobs ?? [];
|
|
7808
7830
|
const contribute = isContributeEnabled() && Array.isArray(index?.contribute) ? index.contribute : [];
|
|
7831
|
+
const contributeNudge = !isContributeEnabled() && !isContributePrompted() && Array.isArray(index?.contribute) && index.contribute.length > 0 ? { count: index.contribute.length } : null;
|
|
7809
7832
|
let matchCount = 0;
|
|
7810
7833
|
let topMatches = [];
|
|
7811
7834
|
let widenReserve = [];
|
|
@@ -7956,7 +7979,12 @@ async function run() {
|
|
|
7956
7979
|
topPeers,
|
|
7957
7980
|
incomingPending,
|
|
7958
7981
|
unreadChat,
|
|
7959
|
-
sessionStale
|
|
7982
|
+
sessionStale,
|
|
7983
|
+
// In-process-only despite being persisted: the render pass receives it as
|
|
7984
|
+
// a function argument below. A future cache READER must not gate on this
|
|
7985
|
+
// field without re-checking isContributeEnabled/isContributePrompted at
|
|
7986
|
+
// read time — the persisted copy can be stale relative to the answer.
|
|
7987
|
+
contributeNudge
|
|
7960
7988
|
};
|
|
7961
7989
|
writeFileSync7(INDEX_CACHE_FILE2, JSON.stringify(cacheEntry), "utf8");
|
|
7962
7990
|
try {
|
|
@@ -7986,6 +8014,7 @@ async function run() {
|
|
|
7986
8014
|
topPeers,
|
|
7987
8015
|
incomingPending,
|
|
7988
8016
|
sessionStale,
|
|
8017
|
+
contributeNudge,
|
|
7989
8018
|
baseUrl: API_URL2,
|
|
7990
8019
|
seenHistory,
|
|
7991
8020
|
widen
|
package/dist/bin/jpi-spinner.js
CHANGED
|
@@ -241,17 +241,32 @@ function buildIncomingIntroLine(incomingPending) {
|
|
|
241
241
|
if (n < 1) return null;
|
|
242
242
|
return n === 1 ? `\u2198 someone wants to connect \xB7 terminalhire intro --list` : `\u2198 ${n} people want to connect \xB7 terminalhire intro --list`;
|
|
243
243
|
}
|
|
244
|
+
function buildContributeNudgeLine(contributeNudge) {
|
|
245
|
+
const n = contributeNudge && typeof contributeNudge.count === "number" ? contributeNudge.count : 0;
|
|
246
|
+
if (n < 1) return null;
|
|
247
|
+
return n === 1 ? "\u2726 an open-source issue that counts toward your r\xE9sum\xE9 \xB7 terminalhire contribute" : `\u2726 ${n} open-source issues that count toward your r\xE9sum\xE9 \xB7 terminalhire contribute`;
|
|
248
|
+
}
|
|
244
249
|
function buildSessionStaleLine(sessionStale) {
|
|
245
250
|
return sessionStale === true ? "\u26A0 terminalhire: linked session expired \u2014 run: terminalhire login" : null;
|
|
246
251
|
}
|
|
247
252
|
function buildSpinnerPool(topMatches, _max = 6, opts = {}) {
|
|
248
|
-
const {
|
|
253
|
+
const {
|
|
254
|
+
sessionTags,
|
|
255
|
+
frequency = "always",
|
|
256
|
+
topPeers,
|
|
257
|
+
incomingPending,
|
|
258
|
+
sessionStale,
|
|
259
|
+
contributeNudge,
|
|
260
|
+
seenHistory
|
|
261
|
+
} = opts;
|
|
249
262
|
const staleLine = buildSessionStaleLine(sessionStale);
|
|
250
263
|
const withStale = (pool2) => staleLine ? [staleLine, ...pool2] : pool2;
|
|
251
264
|
const introLine = buildIncomingIntroLine(incomingPending);
|
|
265
|
+
const contributeLine = buildContributeNudgeLine(contributeNudge);
|
|
252
266
|
const ranked = filterFreshMatches(rankBySessionTags(topMatches, sessionTags), seenHistory);
|
|
253
267
|
if (!Array.isArray(ranked) || ranked.length === 0) {
|
|
254
268
|
if (introLine) return withStale([introLine]);
|
|
269
|
+
if (contributeLine) return withStale([contributeLine]);
|
|
255
270
|
const peerLine = buildPeerLine(topPeers);
|
|
256
271
|
return withStale(peerLine ? [peerLine] : []);
|
|
257
272
|
}
|
|
@@ -259,6 +274,7 @@ function buildSpinnerPool(topMatches, _max = 6, opts = {}) {
|
|
|
259
274
|
const cap = Math.max(1, verbCountForFrequency(frequency, headers.length));
|
|
260
275
|
const pool = [...headers.slice(0, cap), ctaVerb()];
|
|
261
276
|
if (introLine) pool.push(introLine);
|
|
277
|
+
if (contributeLine) pool.push(contributeLine);
|
|
262
278
|
return withStale(pool);
|
|
263
279
|
}
|
|
264
280
|
|
|
@@ -39,11 +39,11 @@ function render() {
|
|
|
39
39
|
if (incoming > 0) parts.push(`\u2709 ${incoming} intro request${incoming === 1 ? "" : "s"}`);
|
|
40
40
|
if (parts.length > 0) {
|
|
41
41
|
let line = parts.join(" \xB7 ");
|
|
42
|
-
line +=
|
|
42
|
+
line += " \u2014 run: th inbox";
|
|
43
43
|
return line;
|
|
44
44
|
}
|
|
45
45
|
if (stale) {
|
|
46
|
-
return "\u26A0 terminalhire session expired \u2014 run:
|
|
46
|
+
return "\u26A0 terminalhire session expired \u2014 run: th link";
|
|
47
47
|
}
|
|
48
48
|
return "";
|
|
49
49
|
} catch {
|
package/dist/bin/jpi.js
CHANGED
|
@@ -264,17 +264,17 @@ try {
|
|
|
264
264
|
let line;
|
|
265
265
|
if (haveRoles) {
|
|
266
266
|
const plural = matchCount === 1 ? "role" : "roles";
|
|
267
|
-
line = `\u2726 ${matchCount} ${plural} match your current work \u2014 run:
|
|
267
|
+
line = `\u2726 ${matchCount} ${plural} match your current work \u2014 run: th jobs`;
|
|
268
268
|
if (incomingCount > 0) line += ` \xB7 \u2709 ${incomingCount} intro request${incomingCount === 1 ? "" : "s"}`;
|
|
269
269
|
if (unreadChatCount > 0) line += ` \xB7 \u{1F4AC} ${unreadChatCount} unread`;
|
|
270
|
-
if (sessionStale) line += ` \xB7 \u26A0 session expired \u2014 run:
|
|
270
|
+
if (sessionStale) line += ` \xB7 \u26A0 session expired \u2014 run: th link`;
|
|
271
271
|
} else if (incomingCount > 0) {
|
|
272
|
-
line = `\u2709 ${incomingCount} intro request${incomingCount === 1 ? "" : "s"} \u2014 run:
|
|
272
|
+
line = `\u2709 ${incomingCount} intro request${incomingCount === 1 ? "" : "s"} \u2014 run: th inbox`;
|
|
273
273
|
if (unreadChatCount > 0) line += ` \xB7 \u{1F4AC} ${unreadChatCount} unread`;
|
|
274
274
|
} else if (unreadChatCount > 0) {
|
|
275
|
-
line = `\u{1F4AC} ${unreadChatCount} unread \u2014 run:
|
|
275
|
+
line = `\u{1F4AC} ${unreadChatCount} unread \u2014 run: th inbox`;
|
|
276
276
|
} else {
|
|
277
|
-
line = `\u26A0 terminalhire session expired \u2014 run:
|
|
277
|
+
line = `\u26A0 terminalhire session expired \u2014 run: th link to restore your connection signals`;
|
|
278
278
|
}
|
|
279
279
|
process.stdout.write(line + "\n");
|
|
280
280
|
if (haveRoles && nudgeMode === "session") {
|
package/dist/bin/spinner.js
CHANGED
|
@@ -357,17 +357,32 @@ function buildIncomingIntroLine(incomingPending) {
|
|
|
357
357
|
if (n < 1) return null;
|
|
358
358
|
return n === 1 ? `\u2198 someone wants to connect \xB7 terminalhire intro --list` : `\u2198 ${n} people want to connect \xB7 terminalhire intro --list`;
|
|
359
359
|
}
|
|
360
|
+
function buildContributeNudgeLine(contributeNudge) {
|
|
361
|
+
const n = contributeNudge && typeof contributeNudge.count === "number" ? contributeNudge.count : 0;
|
|
362
|
+
if (n < 1) return null;
|
|
363
|
+
return n === 1 ? "\u2726 an open-source issue that counts toward your r\xE9sum\xE9 \xB7 terminalhire contribute" : `\u2726 ${n} open-source issues that count toward your r\xE9sum\xE9 \xB7 terminalhire contribute`;
|
|
364
|
+
}
|
|
360
365
|
function buildSessionStaleLine(sessionStale) {
|
|
361
366
|
return sessionStale === true ? "\u26A0 terminalhire: linked session expired \u2014 run: terminalhire login" : null;
|
|
362
367
|
}
|
|
363
368
|
function buildSpinnerPool(topMatches, _max = 6, opts = {}) {
|
|
364
|
-
const {
|
|
369
|
+
const {
|
|
370
|
+
sessionTags,
|
|
371
|
+
frequency = "always",
|
|
372
|
+
topPeers,
|
|
373
|
+
incomingPending,
|
|
374
|
+
sessionStale,
|
|
375
|
+
contributeNudge,
|
|
376
|
+
seenHistory
|
|
377
|
+
} = opts;
|
|
365
378
|
const staleLine = buildSessionStaleLine(sessionStale);
|
|
366
379
|
const withStale = (pool2) => staleLine ? [staleLine, ...pool2] : pool2;
|
|
367
380
|
const introLine = buildIncomingIntroLine(incomingPending);
|
|
381
|
+
const contributeLine = buildContributeNudgeLine(contributeNudge);
|
|
368
382
|
const ranked = filterFreshMatches(rankBySessionTags(topMatches, sessionTags), seenHistory);
|
|
369
383
|
if (!Array.isArray(ranked) || ranked.length === 0) {
|
|
370
384
|
if (introLine) return withStale([introLine]);
|
|
385
|
+
if (contributeLine) return withStale([contributeLine]);
|
|
371
386
|
const peerLine = buildPeerLine(topPeers);
|
|
372
387
|
return withStale(peerLine ? [peerLine] : []);
|
|
373
388
|
}
|
|
@@ -375,6 +390,7 @@ function buildSpinnerPool(topMatches, _max = 6, opts = {}) {
|
|
|
375
390
|
const cap = Math.max(1, verbCountForFrequency(frequency, headers.length));
|
|
376
391
|
const pool = [...headers.slice(0, cap), ctaVerb()];
|
|
377
392
|
if (introLine) pool.push(introLine);
|
|
393
|
+
if (contributeLine) pool.push(contributeLine);
|
|
378
394
|
return withStale(pool);
|
|
379
395
|
}
|
|
380
396
|
|
|
@@ -501,6 +517,7 @@ function renderRefreshSurface(topMatches, sc, opts = {}) {
|
|
|
501
517
|
topPeers: opts.topPeers,
|
|
502
518
|
incomingPending: opts.incomingPending,
|
|
503
519
|
sessionStale: opts.sessionStale,
|
|
520
|
+
contributeNudge: opts.contributeNudge,
|
|
504
521
|
seenHistory
|
|
505
522
|
});
|
|
506
523
|
if (verbs.length > 0) applySpinnerVerbs(verbs, sc.mode);
|
|
@@ -519,6 +536,7 @@ export {
|
|
|
519
536
|
applySpinnerTips,
|
|
520
537
|
applySpinnerVerbs,
|
|
521
538
|
buildContextVerbs,
|
|
539
|
+
buildContributeNudgeLine,
|
|
522
540
|
buildIncomingIntroLine,
|
|
523
541
|
buildPeerLine,
|
|
524
542
|
buildSessionStaleLine,
|
package/dist/src/config.js
CHANGED
|
@@ -59,9 +59,13 @@ function isInboundNudgeMuted() {
|
|
|
59
59
|
function isContributeEnabled() {
|
|
60
60
|
return readConfig().contributeEnabled === true;
|
|
61
61
|
}
|
|
62
|
+
function isContributePrompted() {
|
|
63
|
+
return readConfig().contributePrompted === true;
|
|
64
|
+
}
|
|
62
65
|
export {
|
|
63
66
|
getNudgeMode,
|
|
64
67
|
isContributeEnabled,
|
|
68
|
+
isContributePrompted,
|
|
65
69
|
isInboundNudgeMuted,
|
|
66
70
|
isPeerConnectEnabled,
|
|
67
71
|
parseNudgeMode,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "terminalhire",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.1",
|
|
4
4
|
"description": "Local-first job matching for developers — ambient job matches in the Claude Code spinner. Matching runs on your machine; your profile never leaves it.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|