terminalhire 0.40.4 → 0.40.6
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-bounties.js +14 -5
- package/dist/bin/jpi-chat.js +14 -5
- package/dist/bin/jpi-claim.js +14 -5
- package/dist/bin/jpi-contribute.js +14 -5
- package/dist/bin/jpi-devs.js +14 -5
- package/dist/bin/jpi-dispatch.js +32 -20
- package/dist/bin/jpi-hub.js +14 -5
- package/dist/bin/jpi-inbox.js +14 -5
- package/dist/bin/jpi-init.js +18 -15
- package/dist/bin/jpi-intro.js +14 -5
- package/dist/bin/jpi-jobs.js +14 -5
- package/dist/bin/jpi-learn.js +14 -5
- package/dist/bin/jpi-login.js +14 -5
- package/dist/bin/jpi-mcp.js +14 -5
- package/dist/bin/jpi-profile.js +14 -5
- package/dist/bin/jpi-refresh.js +14 -5
- package/dist/bin/jpi-repo.js +14 -5
- package/dist/bin/jpi-save.js +14 -5
- package/dist/bin/jpi-statusline.js +35 -1
- package/dist/bin/jpi-sync.js +14 -5
- package/dist/bin/jpi-trajectory.js +14 -5
- package/dist/src/crypto-store.js +14 -5
- package/dist/src/intro.js +14 -5
- package/dist/src/profile.js +14 -5
- package/dist/src/repo-experience.js +14 -5
- package/dist/src/trajectory.js +14 -5
- package/package.json +1 -1
- package/statusline-install.js +56 -14
package/dist/bin/jpi-bounties.js
CHANGED
|
@@ -10618,6 +10618,14 @@ function warnStderr(message) {
|
|
|
10618
10618
|
process.stderr.write(`${message}
|
|
10619
10619
|
`);
|
|
10620
10620
|
}
|
|
10621
|
+
function makeWarnOnce() {
|
|
10622
|
+
const seen = /* @__PURE__ */ new Set();
|
|
10623
|
+
return (message) => {
|
|
10624
|
+
if (seen.has(message)) return;
|
|
10625
|
+
seen.add(message);
|
|
10626
|
+
warnStderr(message);
|
|
10627
|
+
};
|
|
10628
|
+
}
|
|
10621
10629
|
function atomicWriteFileSync(filePath, content) {
|
|
10622
10630
|
const dir = dirname(filePath);
|
|
10623
10631
|
ensureStateDirForSecret(dir);
|
|
@@ -10663,11 +10671,11 @@ async function deleteKey() {
|
|
|
10663
10671
|
if (e.code !== "ENOENT") throw e;
|
|
10664
10672
|
}
|
|
10665
10673
|
}
|
|
10666
|
-
async function resolveKey(filePath, opts) {
|
|
10674
|
+
async function resolveKey(filePath, opts, warnOnce) {
|
|
10667
10675
|
if (opts.keyPolicy === "keychain-required") {
|
|
10668
10676
|
const key = await tryLoadFromKeytar();
|
|
10669
10677
|
if (!key) {
|
|
10670
|
-
|
|
10678
|
+
warnOnce(
|
|
10671
10679
|
`crypto-store: OS keychain unavailable \u2014 store at ${filePath} is disabled (no plaintext key file will be written)`
|
|
10672
10680
|
);
|
|
10673
10681
|
return null;
|
|
@@ -10677,8 +10685,9 @@ async function resolveKey(filePath, opts) {
|
|
|
10677
10685
|
return loadOrCreateSharedKey();
|
|
10678
10686
|
}
|
|
10679
10687
|
function createEncryptedStore(filePath, opts) {
|
|
10688
|
+
const warnOnce = makeWarnOnce();
|
|
10680
10689
|
async function read() {
|
|
10681
|
-
const key = await resolveKey(filePath, opts);
|
|
10690
|
+
const key = await resolveKey(filePath, opts, warnOnce);
|
|
10682
10691
|
if (!key) return opts.blank();
|
|
10683
10692
|
if (!existsSync3(filePath)) return opts.blank();
|
|
10684
10693
|
try {
|
|
@@ -10687,12 +10696,12 @@ function createEncryptedStore(filePath, opts) {
|
|
|
10687
10696
|
const plaintext = decrypt(blob, key);
|
|
10688
10697
|
return JSON.parse(plaintext);
|
|
10689
10698
|
} catch {
|
|
10690
|
-
|
|
10699
|
+
warnOnce(`crypto-store: failed to decrypt ${filePath} \u2014 returning blank`);
|
|
10691
10700
|
return opts.blank();
|
|
10692
10701
|
}
|
|
10693
10702
|
}
|
|
10694
10703
|
async function write(value) {
|
|
10695
|
-
const key = await resolveKey(filePath, opts);
|
|
10704
|
+
const key = await resolveKey(filePath, opts, warnOnce);
|
|
10696
10705
|
if (!key) return;
|
|
10697
10706
|
const blob = encrypt(JSON.stringify(value), key);
|
|
10698
10707
|
atomicWriteFileSync(filePath, JSON.stringify(blob, null, 2));
|
package/dist/bin/jpi-chat.js
CHANGED
|
@@ -5478,6 +5478,14 @@ function warnStderr(message) {
|
|
|
5478
5478
|
process.stderr.write(`${message}
|
|
5479
5479
|
`);
|
|
5480
5480
|
}
|
|
5481
|
+
function makeWarnOnce() {
|
|
5482
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5483
|
+
return (message) => {
|
|
5484
|
+
if (seen.has(message)) return;
|
|
5485
|
+
seen.add(message);
|
|
5486
|
+
warnStderr(message);
|
|
5487
|
+
};
|
|
5488
|
+
}
|
|
5481
5489
|
function atomicWriteFileSync(filePath, content) {
|
|
5482
5490
|
const dir = dirname(filePath);
|
|
5483
5491
|
ensureStateDirForSecret(dir);
|
|
@@ -5523,11 +5531,11 @@ async function deleteKey() {
|
|
|
5523
5531
|
if (e.code !== "ENOENT") throw e;
|
|
5524
5532
|
}
|
|
5525
5533
|
}
|
|
5526
|
-
async function resolveKey(filePath, opts) {
|
|
5534
|
+
async function resolveKey(filePath, opts, warnOnce) {
|
|
5527
5535
|
if (opts.keyPolicy === "keychain-required") {
|
|
5528
5536
|
const key = await tryLoadFromKeytar();
|
|
5529
5537
|
if (!key) {
|
|
5530
|
-
|
|
5538
|
+
warnOnce(
|
|
5531
5539
|
`crypto-store: OS keychain unavailable \u2014 store at ${filePath} is disabled (no plaintext key file will be written)`
|
|
5532
5540
|
);
|
|
5533
5541
|
return null;
|
|
@@ -5537,8 +5545,9 @@ async function resolveKey(filePath, opts) {
|
|
|
5537
5545
|
return loadOrCreateSharedKey();
|
|
5538
5546
|
}
|
|
5539
5547
|
function createEncryptedStore(filePath, opts) {
|
|
5548
|
+
const warnOnce = makeWarnOnce();
|
|
5540
5549
|
async function read() {
|
|
5541
|
-
const key = await resolveKey(filePath, opts);
|
|
5550
|
+
const key = await resolveKey(filePath, opts, warnOnce);
|
|
5542
5551
|
if (!key) return opts.blank();
|
|
5543
5552
|
if (!existsSync9(filePath)) return opts.blank();
|
|
5544
5553
|
try {
|
|
@@ -5547,12 +5556,12 @@ function createEncryptedStore(filePath, opts) {
|
|
|
5547
5556
|
const plaintext = decrypt2(blob, key);
|
|
5548
5557
|
return JSON.parse(plaintext);
|
|
5549
5558
|
} catch {
|
|
5550
|
-
|
|
5559
|
+
warnOnce(`crypto-store: failed to decrypt ${filePath} \u2014 returning blank`);
|
|
5551
5560
|
return opts.blank();
|
|
5552
5561
|
}
|
|
5553
5562
|
}
|
|
5554
5563
|
async function write(value) {
|
|
5555
|
-
const key = await resolveKey(filePath, opts);
|
|
5564
|
+
const key = await resolveKey(filePath, opts, warnOnce);
|
|
5556
5565
|
if (!key) return;
|
|
5557
5566
|
const blob = encrypt2(JSON.stringify(value), key);
|
|
5558
5567
|
atomicWriteFileSync(filePath, JSON.stringify(blob, null, 2));
|
package/dist/bin/jpi-claim.js
CHANGED
|
@@ -24831,6 +24831,14 @@ function warnStderr(message) {
|
|
|
24831
24831
|
process.stderr.write(`${message}
|
|
24832
24832
|
`);
|
|
24833
24833
|
}
|
|
24834
|
+
function makeWarnOnce() {
|
|
24835
|
+
const seen = /* @__PURE__ */ new Set();
|
|
24836
|
+
return (message) => {
|
|
24837
|
+
if (seen.has(message)) return;
|
|
24838
|
+
seen.add(message);
|
|
24839
|
+
warnStderr(message);
|
|
24840
|
+
};
|
|
24841
|
+
}
|
|
24834
24842
|
function atomicWriteFileSync(filePath, content) {
|
|
24835
24843
|
const dir = dirname4(filePath);
|
|
24836
24844
|
ensureStateDirForSecret(dir);
|
|
@@ -24876,11 +24884,11 @@ async function deleteKey() {
|
|
|
24876
24884
|
if (e.code !== "ENOENT") throw e;
|
|
24877
24885
|
}
|
|
24878
24886
|
}
|
|
24879
|
-
async function resolveKey(filePath, opts) {
|
|
24887
|
+
async function resolveKey(filePath, opts, warnOnce) {
|
|
24880
24888
|
if (opts.keyPolicy === "keychain-required") {
|
|
24881
24889
|
const key = await tryLoadFromKeytar();
|
|
24882
24890
|
if (!key) {
|
|
24883
|
-
|
|
24891
|
+
warnOnce(
|
|
24884
24892
|
`crypto-store: OS keychain unavailable \u2014 store at ${filePath} is disabled (no plaintext key file will be written)`
|
|
24885
24893
|
);
|
|
24886
24894
|
return null;
|
|
@@ -24890,8 +24898,9 @@ async function resolveKey(filePath, opts) {
|
|
|
24890
24898
|
return loadOrCreateSharedKey();
|
|
24891
24899
|
}
|
|
24892
24900
|
function createEncryptedStore(filePath, opts) {
|
|
24901
|
+
const warnOnce = makeWarnOnce();
|
|
24893
24902
|
async function read() {
|
|
24894
|
-
const key = await resolveKey(filePath, opts);
|
|
24903
|
+
const key = await resolveKey(filePath, opts, warnOnce);
|
|
24895
24904
|
if (!key) return opts.blank();
|
|
24896
24905
|
if (!existsSync6(filePath)) return opts.blank();
|
|
24897
24906
|
try {
|
|
@@ -24900,12 +24909,12 @@ function createEncryptedStore(filePath, opts) {
|
|
|
24900
24909
|
const plaintext = decrypt2(blob, key);
|
|
24901
24910
|
return JSON.parse(plaintext);
|
|
24902
24911
|
} catch {
|
|
24903
|
-
|
|
24912
|
+
warnOnce(`crypto-store: failed to decrypt ${filePath} \u2014 returning blank`);
|
|
24904
24913
|
return opts.blank();
|
|
24905
24914
|
}
|
|
24906
24915
|
}
|
|
24907
24916
|
async function write(value) {
|
|
24908
|
-
const key = await resolveKey(filePath, opts);
|
|
24917
|
+
const key = await resolveKey(filePath, opts, warnOnce);
|
|
24909
24918
|
if (!key) return;
|
|
24910
24919
|
const blob = encrypt2(JSON.stringify(value), key);
|
|
24911
24920
|
atomicWriteFileSync(filePath, JSON.stringify(blob, null, 2));
|
|
@@ -2742,6 +2742,14 @@ function warnStderr(message) {
|
|
|
2742
2742
|
process.stderr.write(`${message}
|
|
2743
2743
|
`);
|
|
2744
2744
|
}
|
|
2745
|
+
function makeWarnOnce() {
|
|
2746
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2747
|
+
return (message) => {
|
|
2748
|
+
if (seen.has(message)) return;
|
|
2749
|
+
seen.add(message);
|
|
2750
|
+
warnStderr(message);
|
|
2751
|
+
};
|
|
2752
|
+
}
|
|
2745
2753
|
function atomicWriteFileSync(filePath, content) {
|
|
2746
2754
|
const dir = dirname(filePath);
|
|
2747
2755
|
ensureStateDirForSecret(dir);
|
|
@@ -2787,11 +2795,11 @@ async function deleteKey() {
|
|
|
2787
2795
|
if (e.code !== "ENOENT") throw e;
|
|
2788
2796
|
}
|
|
2789
2797
|
}
|
|
2790
|
-
async function resolveKey(filePath, opts) {
|
|
2798
|
+
async function resolveKey(filePath, opts, warnOnce) {
|
|
2791
2799
|
if (opts.keyPolicy === "keychain-required") {
|
|
2792
2800
|
const key = await tryLoadFromKeytar();
|
|
2793
2801
|
if (!key) {
|
|
2794
|
-
|
|
2802
|
+
warnOnce(
|
|
2795
2803
|
`crypto-store: OS keychain unavailable \u2014 store at ${filePath} is disabled (no plaintext key file will be written)`
|
|
2796
2804
|
);
|
|
2797
2805
|
return null;
|
|
@@ -2801,8 +2809,9 @@ async function resolveKey(filePath, opts) {
|
|
|
2801
2809
|
return loadOrCreateSharedKey();
|
|
2802
2810
|
}
|
|
2803
2811
|
function createEncryptedStore(filePath, opts) {
|
|
2812
|
+
const warnOnce = makeWarnOnce();
|
|
2804
2813
|
async function read() {
|
|
2805
|
-
const key = await resolveKey(filePath, opts);
|
|
2814
|
+
const key = await resolveKey(filePath, opts, warnOnce);
|
|
2806
2815
|
if (!key) return opts.blank();
|
|
2807
2816
|
if (!existsSync4(filePath)) return opts.blank();
|
|
2808
2817
|
try {
|
|
@@ -2811,12 +2820,12 @@ function createEncryptedStore(filePath, opts) {
|
|
|
2811
2820
|
const plaintext = decrypt(blob, key);
|
|
2812
2821
|
return JSON.parse(plaintext);
|
|
2813
2822
|
} catch {
|
|
2814
|
-
|
|
2823
|
+
warnOnce(`crypto-store: failed to decrypt ${filePath} \u2014 returning blank`);
|
|
2815
2824
|
return opts.blank();
|
|
2816
2825
|
}
|
|
2817
2826
|
}
|
|
2818
2827
|
async function write(value) {
|
|
2819
|
-
const key = await resolveKey(filePath, opts);
|
|
2828
|
+
const key = await resolveKey(filePath, opts, warnOnce);
|
|
2820
2829
|
if (!key) return;
|
|
2821
2830
|
const blob = encrypt(JSON.stringify(value), key);
|
|
2822
2831
|
atomicWriteFileSync(filePath, JSON.stringify(blob, null, 2));
|
package/dist/bin/jpi-devs.js
CHANGED
|
@@ -10566,6 +10566,14 @@ function warnStderr(message) {
|
|
|
10566
10566
|
process.stderr.write(`${message}
|
|
10567
10567
|
`);
|
|
10568
10568
|
}
|
|
10569
|
+
function makeWarnOnce() {
|
|
10570
|
+
const seen = /* @__PURE__ */ new Set();
|
|
10571
|
+
return (message) => {
|
|
10572
|
+
if (seen.has(message)) return;
|
|
10573
|
+
seen.add(message);
|
|
10574
|
+
warnStderr(message);
|
|
10575
|
+
};
|
|
10576
|
+
}
|
|
10569
10577
|
function atomicWriteFileSync(filePath, content) {
|
|
10570
10578
|
const dir = dirname(filePath);
|
|
10571
10579
|
ensureStateDirForSecret(dir);
|
|
@@ -10611,11 +10619,11 @@ async function deleteKey() {
|
|
|
10611
10619
|
if (e.code !== "ENOENT") throw e;
|
|
10612
10620
|
}
|
|
10613
10621
|
}
|
|
10614
|
-
async function resolveKey(filePath, opts) {
|
|
10622
|
+
async function resolveKey(filePath, opts, warnOnce) {
|
|
10615
10623
|
if (opts.keyPolicy === "keychain-required") {
|
|
10616
10624
|
const key = await tryLoadFromKeytar();
|
|
10617
10625
|
if (!key) {
|
|
10618
|
-
|
|
10626
|
+
warnOnce(
|
|
10619
10627
|
`crypto-store: OS keychain unavailable \u2014 store at ${filePath} is disabled (no plaintext key file will be written)`
|
|
10620
10628
|
);
|
|
10621
10629
|
return null;
|
|
@@ -10625,8 +10633,9 @@ async function resolveKey(filePath, opts) {
|
|
|
10625
10633
|
return loadOrCreateSharedKey();
|
|
10626
10634
|
}
|
|
10627
10635
|
function createEncryptedStore(filePath, opts) {
|
|
10636
|
+
const warnOnce = makeWarnOnce();
|
|
10628
10637
|
async function read() {
|
|
10629
|
-
const key = await resolveKey(filePath, opts);
|
|
10638
|
+
const key = await resolveKey(filePath, opts, warnOnce);
|
|
10630
10639
|
if (!key) return opts.blank();
|
|
10631
10640
|
if (!existsSync3(filePath)) return opts.blank();
|
|
10632
10641
|
try {
|
|
@@ -10635,12 +10644,12 @@ function createEncryptedStore(filePath, opts) {
|
|
|
10635
10644
|
const plaintext = decrypt(blob, key);
|
|
10636
10645
|
return JSON.parse(plaintext);
|
|
10637
10646
|
} catch {
|
|
10638
|
-
|
|
10647
|
+
warnOnce(`crypto-store: failed to decrypt ${filePath} \u2014 returning blank`);
|
|
10639
10648
|
return opts.blank();
|
|
10640
10649
|
}
|
|
10641
10650
|
}
|
|
10642
10651
|
async function write(value) {
|
|
10643
|
-
const key = await resolveKey(filePath, opts);
|
|
10652
|
+
const key = await resolveKey(filePath, opts, warnOnce);
|
|
10644
10653
|
if (!key) return;
|
|
10645
10654
|
const blob = encrypt(JSON.stringify(value), key);
|
|
10646
10655
|
atomicWriteFileSync(filePath, JSON.stringify(blob, null, 2));
|
package/dist/bin/jpi-dispatch.js
CHANGED
|
@@ -11928,6 +11928,14 @@ function warnStderr(message) {
|
|
|
11928
11928
|
process.stderr.write(`${message}
|
|
11929
11929
|
`);
|
|
11930
11930
|
}
|
|
11931
|
+
function makeWarnOnce() {
|
|
11932
|
+
const seen = /* @__PURE__ */ new Set();
|
|
11933
|
+
return (message) => {
|
|
11934
|
+
if (seen.has(message)) return;
|
|
11935
|
+
seen.add(message);
|
|
11936
|
+
warnStderr(message);
|
|
11937
|
+
};
|
|
11938
|
+
}
|
|
11931
11939
|
function atomicWriteFileSync(filePath, content) {
|
|
11932
11940
|
const dir = dirname(filePath);
|
|
11933
11941
|
ensureStateDirForSecret(dir);
|
|
@@ -11973,11 +11981,11 @@ async function deleteKey() {
|
|
|
11973
11981
|
if (e.code !== "ENOENT") throw e;
|
|
11974
11982
|
}
|
|
11975
11983
|
}
|
|
11976
|
-
async function resolveKey(filePath, opts) {
|
|
11984
|
+
async function resolveKey(filePath, opts, warnOnce) {
|
|
11977
11985
|
if (opts.keyPolicy === "keychain-required") {
|
|
11978
11986
|
const key = await tryLoadFromKeytar();
|
|
11979
11987
|
if (!key) {
|
|
11980
|
-
|
|
11988
|
+
warnOnce(
|
|
11981
11989
|
`crypto-store: OS keychain unavailable \u2014 store at ${filePath} is disabled (no plaintext key file will be written)`
|
|
11982
11990
|
);
|
|
11983
11991
|
return null;
|
|
@@ -11987,8 +11995,9 @@ async function resolveKey(filePath, opts) {
|
|
|
11987
11995
|
return loadOrCreateSharedKey();
|
|
11988
11996
|
}
|
|
11989
11997
|
function createEncryptedStore(filePath, opts) {
|
|
11998
|
+
const warnOnce = makeWarnOnce();
|
|
11990
11999
|
async function read() {
|
|
11991
|
-
const key = await resolveKey(filePath, opts);
|
|
12000
|
+
const key = await resolveKey(filePath, opts, warnOnce);
|
|
11992
12001
|
if (!key) return opts.blank();
|
|
11993
12002
|
if (!existsSync8(filePath)) return opts.blank();
|
|
11994
12003
|
try {
|
|
@@ -11997,12 +12006,12 @@ function createEncryptedStore(filePath, opts) {
|
|
|
11997
12006
|
const plaintext = decrypt2(blob, key);
|
|
11998
12007
|
return JSON.parse(plaintext);
|
|
11999
12008
|
} catch {
|
|
12000
|
-
|
|
12009
|
+
warnOnce(`crypto-store: failed to decrypt ${filePath} \u2014 returning blank`);
|
|
12001
12010
|
return opts.blank();
|
|
12002
12011
|
}
|
|
12003
12012
|
}
|
|
12004
12013
|
async function write(value) {
|
|
12005
|
-
const key = await resolveKey(filePath, opts);
|
|
12014
|
+
const key = await resolveKey(filePath, opts, warnOnce);
|
|
12006
12015
|
if (!key) return;
|
|
12007
12016
|
const blob = encrypt2(JSON.stringify(value), key);
|
|
12008
12017
|
atomicWriteFileSync(filePath, JSON.stringify(blob, null, 2));
|
|
@@ -63618,15 +63627,11 @@ async function run25() {
|
|
|
63618
63627
|
console.log("");
|
|
63619
63628
|
console.log(" Fetching anonymous job index (no dev data sent)...");
|
|
63620
63629
|
const jobsScript = resolveScript("jpi-jobs");
|
|
63621
|
-
const seedChild = spawnSync3(
|
|
63622
|
-
|
|
63623
|
-
|
|
63624
|
-
|
|
63625
|
-
|
|
63626
|
-
env: { ...process.env, TERMINALHIRE_SEED_ONLY: "1" },
|
|
63627
|
-
timeout: 15e3
|
|
63628
|
-
}
|
|
63629
|
-
);
|
|
63630
|
+
const seedChild = spawnSync3(process.execPath, [jobsScript, "--limit", "0"], {
|
|
63631
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
63632
|
+
env: { ...process.env, TERMINALHIRE_SEED_ONLY: "1" },
|
|
63633
|
+
timeout: 15e3
|
|
63634
|
+
});
|
|
63630
63635
|
if (seedChild.status === 0) {
|
|
63631
63636
|
console.log(" Job cache seeded successfully.");
|
|
63632
63637
|
} else {
|
|
@@ -63658,7 +63663,9 @@ async function run25() {
|
|
|
63658
63663
|
console.log("");
|
|
63659
63664
|
console.log(" This is the only step that modifies a system file.");
|
|
63660
63665
|
console.log(" A timestamped backup is created before any change.");
|
|
63661
|
-
console.log(
|
|
63666
|
+
console.log(
|
|
63667
|
+
" Disable at any time: node install.js --uninstall (or terminalhire spinner --off)"
|
|
63668
|
+
);
|
|
63662
63669
|
console.log("");
|
|
63663
63670
|
try {
|
|
63664
63671
|
const installMod = await import(pathToFileURL(resolveInstallJs()).href);
|
|
@@ -63677,9 +63684,10 @@ async function run25() {
|
|
|
63677
63684
|
console.log("");
|
|
63678
63685
|
console.log(" A statusLine that shows ONLY personal connection signals \u2014 \u{1F4AC} unread");
|
|
63679
63686
|
console.log(" messages and inbound intro requests. Never job ads (those stay in the");
|
|
63680
|
-
console.log(" spinner). Local cache read, zero network.
|
|
63681
|
-
console.log("
|
|
63682
|
-
console.log("
|
|
63687
|
+
console.log(" spinner). Local cache read, zero network. On by default; backs up and");
|
|
63688
|
+
console.log(" preserves any existing statusLine, and stays current across plugin");
|
|
63689
|
+
console.log(" updates. Answer n to skip, or remove later with:");
|
|
63690
|
+
console.log(" terminalhire statusline --off");
|
|
63683
63691
|
console.log("");
|
|
63684
63692
|
try {
|
|
63685
63693
|
const statuslineMod = await import(pathToFileURL(resolveStatuslineInstallJs()).href);
|
|
@@ -63687,7 +63695,9 @@ async function run25() {
|
|
|
63687
63695
|
await statuslineMod.installStatusline({ ask: ask4 });
|
|
63688
63696
|
} else {
|
|
63689
63697
|
console.log("");
|
|
63690
|
-
console.log(
|
|
63698
|
+
console.log(
|
|
63699
|
+
" statusLine setup unavailable in this build. Run manually: node statusline-install.js"
|
|
63700
|
+
);
|
|
63691
63701
|
}
|
|
63692
63702
|
} catch {
|
|
63693
63703
|
console.log("");
|
|
@@ -63716,7 +63726,9 @@ async function run25() {
|
|
|
63716
63726
|
console.log(" this terminal (one-time OS registration; macOS may show an Automation");
|
|
63717
63727
|
console.log(" prompt the first time a link is opened). Nothing is sent anywhere \u2014 it");
|
|
63718
63728
|
console.log(" only wires th://claim/<token> links on this machine to a local, read-only");
|
|
63719
|
-
console.log(
|
|
63729
|
+
console.log(
|
|
63730
|
+
" `terminalhire claim preview <token>`. Undo any time: terminalhire protocol unregister"
|
|
63731
|
+
);
|
|
63720
63732
|
console.log("");
|
|
63721
63733
|
const protocolAnswer = await ask4("Register th:// claim links now? [Y/n] (Enter = yes): ");
|
|
63722
63734
|
const doProtocol = protocolAnswer === "" || protocolAnswer === "y" || protocolAnswer === "yes";
|
package/dist/bin/jpi-hub.js
CHANGED
|
@@ -11198,6 +11198,14 @@ function warnStderr(message) {
|
|
|
11198
11198
|
process.stderr.write(`${message}
|
|
11199
11199
|
`);
|
|
11200
11200
|
}
|
|
11201
|
+
function makeWarnOnce() {
|
|
11202
|
+
const seen = /* @__PURE__ */ new Set();
|
|
11203
|
+
return (message) => {
|
|
11204
|
+
if (seen.has(message)) return;
|
|
11205
|
+
seen.add(message);
|
|
11206
|
+
warnStderr(message);
|
|
11207
|
+
};
|
|
11208
|
+
}
|
|
11201
11209
|
function atomicWriteFileSync(filePath, content) {
|
|
11202
11210
|
const dir = dirname(filePath);
|
|
11203
11211
|
ensureStateDirForSecret(dir);
|
|
@@ -11243,11 +11251,11 @@ async function deleteKey() {
|
|
|
11243
11251
|
if (e.code !== "ENOENT") throw e;
|
|
11244
11252
|
}
|
|
11245
11253
|
}
|
|
11246
|
-
async function resolveKey(filePath, opts) {
|
|
11254
|
+
async function resolveKey(filePath, opts, warnOnce) {
|
|
11247
11255
|
if (opts.keyPolicy === "keychain-required") {
|
|
11248
11256
|
const key = await tryLoadFromKeytar();
|
|
11249
11257
|
if (!key) {
|
|
11250
|
-
|
|
11258
|
+
warnOnce(
|
|
11251
11259
|
`crypto-store: OS keychain unavailable \u2014 store at ${filePath} is disabled (no plaintext key file will be written)`
|
|
11252
11260
|
);
|
|
11253
11261
|
return null;
|
|
@@ -11257,8 +11265,9 @@ async function resolveKey(filePath, opts) {
|
|
|
11257
11265
|
return loadOrCreateSharedKey();
|
|
11258
11266
|
}
|
|
11259
11267
|
function createEncryptedStore(filePath, opts) {
|
|
11268
|
+
const warnOnce = makeWarnOnce();
|
|
11260
11269
|
async function read() {
|
|
11261
|
-
const key = await resolveKey(filePath, opts);
|
|
11270
|
+
const key = await resolveKey(filePath, opts, warnOnce);
|
|
11262
11271
|
if (!key) return opts.blank();
|
|
11263
11272
|
if (!existsSync4(filePath)) return opts.blank();
|
|
11264
11273
|
try {
|
|
@@ -11267,12 +11276,12 @@ function createEncryptedStore(filePath, opts) {
|
|
|
11267
11276
|
const plaintext = decrypt(blob, key);
|
|
11268
11277
|
return JSON.parse(plaintext);
|
|
11269
11278
|
} catch {
|
|
11270
|
-
|
|
11279
|
+
warnOnce(`crypto-store: failed to decrypt ${filePath} \u2014 returning blank`);
|
|
11271
11280
|
return opts.blank();
|
|
11272
11281
|
}
|
|
11273
11282
|
}
|
|
11274
11283
|
async function write(value) {
|
|
11275
|
-
const key = await resolveKey(filePath, opts);
|
|
11284
|
+
const key = await resolveKey(filePath, opts, warnOnce);
|
|
11276
11285
|
if (!key) return;
|
|
11277
11286
|
const blob = encrypt(JSON.stringify(value), key);
|
|
11278
11287
|
atomicWriteFileSync(filePath, JSON.stringify(blob, null, 2));
|
package/dist/bin/jpi-inbox.js
CHANGED
|
@@ -5478,6 +5478,14 @@ function warnStderr(message) {
|
|
|
5478
5478
|
process.stderr.write(`${message}
|
|
5479
5479
|
`);
|
|
5480
5480
|
}
|
|
5481
|
+
function makeWarnOnce() {
|
|
5482
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5483
|
+
return (message) => {
|
|
5484
|
+
if (seen.has(message)) return;
|
|
5485
|
+
seen.add(message);
|
|
5486
|
+
warnStderr(message);
|
|
5487
|
+
};
|
|
5488
|
+
}
|
|
5481
5489
|
function atomicWriteFileSync(filePath, content) {
|
|
5482
5490
|
const dir = dirname(filePath);
|
|
5483
5491
|
ensureStateDirForSecret(dir);
|
|
@@ -5523,11 +5531,11 @@ async function deleteKey() {
|
|
|
5523
5531
|
if (e.code !== "ENOENT") throw e;
|
|
5524
5532
|
}
|
|
5525
5533
|
}
|
|
5526
|
-
async function resolveKey(filePath, opts) {
|
|
5534
|
+
async function resolveKey(filePath, opts, warnOnce) {
|
|
5527
5535
|
if (opts.keyPolicy === "keychain-required") {
|
|
5528
5536
|
const key = await tryLoadFromKeytar();
|
|
5529
5537
|
if (!key) {
|
|
5530
|
-
|
|
5538
|
+
warnOnce(
|
|
5531
5539
|
`crypto-store: OS keychain unavailable \u2014 store at ${filePath} is disabled (no plaintext key file will be written)`
|
|
5532
5540
|
);
|
|
5533
5541
|
return null;
|
|
@@ -5537,8 +5545,9 @@ async function resolveKey(filePath, opts) {
|
|
|
5537
5545
|
return loadOrCreateSharedKey();
|
|
5538
5546
|
}
|
|
5539
5547
|
function createEncryptedStore(filePath, opts) {
|
|
5548
|
+
const warnOnce = makeWarnOnce();
|
|
5540
5549
|
async function read() {
|
|
5541
|
-
const key = await resolveKey(filePath, opts);
|
|
5550
|
+
const key = await resolveKey(filePath, opts, warnOnce);
|
|
5542
5551
|
if (!key) return opts.blank();
|
|
5543
5552
|
if (!existsSync9(filePath)) return opts.blank();
|
|
5544
5553
|
try {
|
|
@@ -5547,12 +5556,12 @@ function createEncryptedStore(filePath, opts) {
|
|
|
5547
5556
|
const plaintext = decrypt2(blob, key);
|
|
5548
5557
|
return JSON.parse(plaintext);
|
|
5549
5558
|
} catch {
|
|
5550
|
-
|
|
5559
|
+
warnOnce(`crypto-store: failed to decrypt ${filePath} \u2014 returning blank`);
|
|
5551
5560
|
return opts.blank();
|
|
5552
5561
|
}
|
|
5553
5562
|
}
|
|
5554
5563
|
async function write(value) {
|
|
5555
|
-
const key = await resolveKey(filePath, opts);
|
|
5564
|
+
const key = await resolveKey(filePath, opts, warnOnce);
|
|
5556
5565
|
if (!key) return;
|
|
5557
5566
|
const blob = encrypt2(JSON.stringify(value), key);
|
|
5558
5567
|
atomicWriteFileSync(filePath, JSON.stringify(blob, null, 2));
|
package/dist/bin/jpi-init.js
CHANGED
|
@@ -10772,15 +10772,11 @@ async function run() {
|
|
|
10772
10772
|
console.log("");
|
|
10773
10773
|
console.log(" Fetching anonymous job index (no dev data sent)...");
|
|
10774
10774
|
const jobsScript = resolveScript("jpi-jobs");
|
|
10775
|
-
const seedChild = spawnSync(
|
|
10776
|
-
|
|
10777
|
-
|
|
10778
|
-
|
|
10779
|
-
|
|
10780
|
-
env: { ...process.env, TERMINALHIRE_SEED_ONLY: "1" },
|
|
10781
|
-
timeout: 15e3
|
|
10782
|
-
}
|
|
10783
|
-
);
|
|
10775
|
+
const seedChild = spawnSync(process.execPath, [jobsScript, "--limit", "0"], {
|
|
10776
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
10777
|
+
env: { ...process.env, TERMINALHIRE_SEED_ONLY: "1" },
|
|
10778
|
+
timeout: 15e3
|
|
10779
|
+
});
|
|
10784
10780
|
if (seedChild.status === 0) {
|
|
10785
10781
|
console.log(" Job cache seeded successfully.");
|
|
10786
10782
|
} else {
|
|
@@ -10812,7 +10808,9 @@ async function run() {
|
|
|
10812
10808
|
console.log("");
|
|
10813
10809
|
console.log(" This is the only step that modifies a system file.");
|
|
10814
10810
|
console.log(" A timestamped backup is created before any change.");
|
|
10815
|
-
console.log(
|
|
10811
|
+
console.log(
|
|
10812
|
+
" Disable at any time: node install.js --uninstall (or terminalhire spinner --off)"
|
|
10813
|
+
);
|
|
10816
10814
|
console.log("");
|
|
10817
10815
|
try {
|
|
10818
10816
|
const installMod = await import(pathToFileURL(resolveInstallJs()).href);
|
|
@@ -10831,9 +10829,10 @@ async function run() {
|
|
|
10831
10829
|
console.log("");
|
|
10832
10830
|
console.log(" A statusLine that shows ONLY personal connection signals \u2014 \u{1F4AC} unread");
|
|
10833
10831
|
console.log(" messages and inbound intro requests. Never job ads (those stay in the");
|
|
10834
|
-
console.log(" spinner). Local cache read, zero network.
|
|
10835
|
-
console.log("
|
|
10836
|
-
console.log("
|
|
10832
|
+
console.log(" spinner). Local cache read, zero network. On by default; backs up and");
|
|
10833
|
+
console.log(" preserves any existing statusLine, and stays current across plugin");
|
|
10834
|
+
console.log(" updates. Answer n to skip, or remove later with:");
|
|
10835
|
+
console.log(" terminalhire statusline --off");
|
|
10837
10836
|
console.log("");
|
|
10838
10837
|
try {
|
|
10839
10838
|
const statuslineMod = await import(pathToFileURL(resolveStatuslineInstallJs()).href);
|
|
@@ -10841,7 +10840,9 @@ async function run() {
|
|
|
10841
10840
|
await statuslineMod.installStatusline({ ask });
|
|
10842
10841
|
} else {
|
|
10843
10842
|
console.log("");
|
|
10844
|
-
console.log(
|
|
10843
|
+
console.log(
|
|
10844
|
+
" statusLine setup unavailable in this build. Run manually: node statusline-install.js"
|
|
10845
|
+
);
|
|
10845
10846
|
}
|
|
10846
10847
|
} catch {
|
|
10847
10848
|
console.log("");
|
|
@@ -10870,7 +10871,9 @@ async function run() {
|
|
|
10870
10871
|
console.log(" this terminal (one-time OS registration; macOS may show an Automation");
|
|
10871
10872
|
console.log(" prompt the first time a link is opened). Nothing is sent anywhere \u2014 it");
|
|
10872
10873
|
console.log(" only wires th://claim/<token> links on this machine to a local, read-only");
|
|
10873
|
-
console.log(
|
|
10874
|
+
console.log(
|
|
10875
|
+
" `terminalhire claim preview <token>`. Undo any time: terminalhire protocol unregister"
|
|
10876
|
+
);
|
|
10874
10877
|
console.log("");
|
|
10875
10878
|
const protocolAnswer = await ask("Register th:// claim links now? [Y/n] (Enter = yes): ");
|
|
10876
10879
|
const doProtocol = protocolAnswer === "" || protocolAnswer === "y" || protocolAnswer === "yes";
|
package/dist/bin/jpi-intro.js
CHANGED
|
@@ -1547,6 +1547,14 @@ function warnStderr(message) {
|
|
|
1547
1547
|
process.stderr.write(`${message}
|
|
1548
1548
|
`);
|
|
1549
1549
|
}
|
|
1550
|
+
function makeWarnOnce() {
|
|
1551
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1552
|
+
return (message) => {
|
|
1553
|
+
if (seen.has(message)) return;
|
|
1554
|
+
seen.add(message);
|
|
1555
|
+
warnStderr(message);
|
|
1556
|
+
};
|
|
1557
|
+
}
|
|
1550
1558
|
function atomicWriteFileSync(filePath, content) {
|
|
1551
1559
|
const dir = dirname(filePath);
|
|
1552
1560
|
ensureStateDirForSecret(dir);
|
|
@@ -1592,11 +1600,11 @@ async function deleteKey() {
|
|
|
1592
1600
|
if (e.code !== "ENOENT") throw e;
|
|
1593
1601
|
}
|
|
1594
1602
|
}
|
|
1595
|
-
async function resolveKey(filePath, opts) {
|
|
1603
|
+
async function resolveKey(filePath, opts, warnOnce) {
|
|
1596
1604
|
if (opts.keyPolicy === "keychain-required") {
|
|
1597
1605
|
const key = await tryLoadFromKeytar();
|
|
1598
1606
|
if (!key) {
|
|
1599
|
-
|
|
1607
|
+
warnOnce(
|
|
1600
1608
|
`crypto-store: OS keychain unavailable \u2014 store at ${filePath} is disabled (no plaintext key file will be written)`
|
|
1601
1609
|
);
|
|
1602
1610
|
return null;
|
|
@@ -1606,8 +1614,9 @@ async function resolveKey(filePath, opts) {
|
|
|
1606
1614
|
return loadOrCreateSharedKey();
|
|
1607
1615
|
}
|
|
1608
1616
|
function createEncryptedStore(filePath, opts) {
|
|
1617
|
+
const warnOnce = makeWarnOnce();
|
|
1609
1618
|
async function read() {
|
|
1610
|
-
const key = await resolveKey(filePath, opts);
|
|
1619
|
+
const key = await resolveKey(filePath, opts, warnOnce);
|
|
1611
1620
|
if (!key) return opts.blank();
|
|
1612
1621
|
if (!existsSync4(filePath)) return opts.blank();
|
|
1613
1622
|
try {
|
|
@@ -1616,12 +1625,12 @@ function createEncryptedStore(filePath, opts) {
|
|
|
1616
1625
|
const plaintext = decrypt(blob, key);
|
|
1617
1626
|
return JSON.parse(plaintext);
|
|
1618
1627
|
} catch {
|
|
1619
|
-
|
|
1628
|
+
warnOnce(`crypto-store: failed to decrypt ${filePath} \u2014 returning blank`);
|
|
1620
1629
|
return opts.blank();
|
|
1621
1630
|
}
|
|
1622
1631
|
}
|
|
1623
1632
|
async function write(value) {
|
|
1624
|
-
const key = await resolveKey(filePath, opts);
|
|
1633
|
+
const key = await resolveKey(filePath, opts, warnOnce);
|
|
1625
1634
|
if (!key) return;
|
|
1626
1635
|
const blob = encrypt(JSON.stringify(value), key);
|
|
1627
1636
|
atomicWriteFileSync(filePath, JSON.stringify(blob, null, 2));
|