ccdeck 3.22.6 → 3.22.7
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/web/index.html
CHANGED
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
document.documentElement.setAttribute("data-theme", stored === "light" ? "light" : "dark");
|
|
41
41
|
})();
|
|
42
42
|
</script>
|
|
43
|
-
<script type="module" crossorigin src="/assets/index-
|
|
43
|
+
<script type="module" crossorigin src="/assets/index-AeLjqiYS.js"></script>
|
|
44
44
|
<link rel="stylesheet" crossorigin href="/assets/index-D0ZefIva.css">
|
|
45
45
|
</head>
|
|
46
46
|
<body>
|
package/package.json
CHANGED
|
@@ -31,7 +31,10 @@ export const REACTIONS = ["notify", "close-tab", "quit-browser"];
|
|
|
31
31
|
|
|
32
32
|
export const DEFAULTS = {
|
|
33
33
|
v: 1,
|
|
34
|
-
|
|
34
|
+
// ON unless somebody switches it off (since 3.22.7; off before). A saved
|
|
35
|
+
// `false` still wins — normalise() takes any real boolean — so an upgrade
|
|
36
|
+
// starts watching only on a deck that never saved this field.
|
|
37
|
+
enabled: true,
|
|
35
38
|
reaction: "notify",
|
|
36
39
|
quietMinutes: 15,
|
|
37
40
|
gapMinutes: 15,
|
|
@@ -124,7 +127,7 @@ export function normalise(raw) {
|
|
|
124
127
|
typeof v === "number" && Number.isFinite(v) && v >= lo && v <= hi ? v : fallback;
|
|
125
128
|
return {
|
|
126
129
|
v: 1,
|
|
127
|
-
enabled: it.enabled ===
|
|
130
|
+
enabled: typeof it.enabled === "boolean" ? it.enabled : DEFAULTS.enabled,
|
|
128
131
|
reaction: REACTIONS.includes(it.reaction) ? it.reaction : DEFAULTS.reaction,
|
|
129
132
|
quietMinutes: num(it.quietMinutes, DEFAULTS.quietMinutes, 1, 24 * 60),
|
|
130
133
|
gapMinutes: num(it.gapMinutes, DEFAULTS.gapMinutes, 1, 24 * 60),
|
|
@@ -49,37 +49,46 @@ export const prefsPath = (home = deckDataDir()) => join(prefsDir(home), "prefs.j
|
|
|
49
49
|
|
|
50
50
|
/**
|
|
51
51
|
* Every preference the deck keeps, with the answer it gives when there is no
|
|
52
|
-
* file
|
|
53
|
-
*
|
|
52
|
+
* file. A saved choice always wins over these — normalise() takes any real
|
|
53
|
+
* boolean — so changing one here reaches only decks that never saved that
|
|
54
|
+
* field, and nobody's saved setting is flipped by an upgrade.
|
|
54
55
|
*
|
|
55
|
-
* `notifications` defaults
|
|
56
|
-
*
|
|
57
|
-
* on
|
|
56
|
+
* `notifications` defaults OFF since 3.22.7. The deck's own sounds are how it
|
|
57
|
+
* gets attention by default; a desktop notification is something a person
|
|
58
|
+
* turns on. It defaulted on from 3.7.0 until then, and a deck that saved that
|
|
59
|
+
* `true` keeps it.
|
|
58
60
|
*/
|
|
59
61
|
export const DEFAULTS = Object.freeze({
|
|
60
|
-
notifications:
|
|
62
|
+
notifications: false,
|
|
61
63
|
// Whether the deck may update itself: restart into code already on disk once
|
|
62
64
|
// it is idle, and — while nobody is looking — install a newer release and
|
|
63
65
|
// restart into that (auto-update.mjs). ON, because this is the banner's
|
|
64
66
|
// `auto when idle`, which defaulted on as a localStorage key; it moved here so
|
|
65
67
|
// the server can read it with no page open.
|
|
66
68
|
autoUpdate: true,
|
|
67
|
-
// LAN sync,
|
|
68
|
-
// this file has ever held, which is why the
|
|
69
|
+
// LAN sync, ON unless somebody turns it off (since 3.22.7; off before).
|
|
70
|
+
// `passphrase` is the only secret this file has ever held, which is why the
|
|
71
|
+
// write below names a mode. AGENTS_DECK_NO_LAN=1 keeps a deck off the network
|
|
72
|
+
// whatever this file says — see lanEnabled.
|
|
69
73
|
lan: Object.freeze({
|
|
70
|
-
enabled:
|
|
71
|
-
// WHO PAIRS WITH WHOM, WITHOUT ANYBODY PRESSING ANYTHING.
|
|
72
|
-
// decks on one network find each other and
|
|
73
|
-
// a person with three of their own machines wants and had to
|
|
74
|
-
// six times.
|
|
74
|
+
enabled: true, name: "", secret: "", shared: [], manual: [], trusted: [], port: 0,
|
|
75
|
+
// WHO PAIRS WITH WHOM, WITHOUT ANYBODY PRESSING ANYTHING. Asking is on, so
|
|
76
|
+
// two decks on one network find each other and send each other a request —
|
|
77
|
+
// which is what a person with three of their own machines wants and had to
|
|
78
|
+
// do by hand six times.
|
|
75
79
|
//
|
|
76
|
-
//
|
|
77
|
-
//
|
|
78
|
-
//
|
|
79
|
-
//
|
|
80
|
-
//
|
|
80
|
+
// Saying yes is OFF, and that is the half that had to change when `enabled`
|
|
81
|
+
// did. Auto-accept is the accept button pressed in advance, and it was a
|
|
82
|
+
// fair trade while every deck on the network belonged to somebody who had
|
|
83
|
+
// switched this on deliberately. With the feature on for everybody, every
|
|
84
|
+
// ccdeck in an office would pair with every other one in silence — and a
|
|
85
|
+
// login ticked later goes to everything paired. So a pairing takes one
|
|
86
|
+
// press of accept on the machine that was asked.
|
|
87
|
+
//
|
|
88
|
+
// `shared` is empty either way, so a deck that pairs is offered nothing
|
|
89
|
+
// until somebody ticks a login: the gate that did not change.
|
|
81
90
|
autoAsk: true,
|
|
82
|
-
autoAccept:
|
|
91
|
+
autoAccept: false,
|
|
83
92
|
// What somebody HERE calls another deck, keyed by its fingerprint. The name
|
|
84
93
|
// a deck gives itself is its owner's to choose; this is the other half.
|
|
85
94
|
aliases: Object.freeze({}),
|
|
@@ -140,7 +149,7 @@ function normaliseLan(raw) {
|
|
|
140
149
|
const src = raw && typeof raw === "object" ? raw : {};
|
|
141
150
|
const strings = v => (Array.isArray(v) ? v.filter(x => typeof x === "string") : []);
|
|
142
151
|
return {
|
|
143
|
-
enabled: typeof src.enabled === "boolean" ? src.enabled :
|
|
152
|
+
enabled: typeof src.enabled === "boolean" ? src.enabled : DEFAULTS.lan.enabled,
|
|
144
153
|
name: typeof src.name === "string" ? src.name : "",
|
|
145
154
|
// THIS DECK'S PRIVATE KEY, and the only secret this file has ever held —
|
|
146
155
|
// which is why the write below names a mode rather than taking the umask's.
|
|
@@ -175,12 +184,14 @@ function normaliseLan(raw) {
|
|
|
175
184
|
// anybody pressing `ask` — the outbound half, which gives nothing away: the
|
|
176
185
|
// machine on the other end still answers it, by hand or by the switch below.
|
|
177
186
|
autoAsk: typeof src.autoAsk === "boolean" ? src.autoAsk : true,
|
|
178
|
-
// AND SAY YES. Every deck that finishes a
|
|
179
|
-
// trusted is pinned without anybody being
|
|
180
|
-
// in advance, and it hands whoever asks a
|
|
181
|
-
// shares. Absent means the default above
|
|
182
|
-
//
|
|
183
|
-
|
|
187
|
+
// AND SAY YES, once somebody has turned this on. Every deck that finishes a
|
|
188
|
+
// handshake and is not already trusted is then pinned without anybody being
|
|
189
|
+
// asked — the accept button pressed in advance, and it hands whoever asks a
|
|
190
|
+
// copy of every login this deck shares. Absent means the default above,
|
|
191
|
+
// which is off since the feature itself started on; only a real boolean
|
|
192
|
+
// overrides it, because a truthy string from a hand-edited file is not an
|
|
193
|
+
// answer.
|
|
194
|
+
autoAccept: typeof src.autoAccept === "boolean" ? src.autoAccept : DEFAULTS.lan.autoAccept,
|
|
184
195
|
};
|
|
185
196
|
}
|
|
186
197
|
|
|
@@ -286,6 +297,20 @@ export function notificationsOn(prefs, env = process.env) {
|
|
|
286
297
|
return normalise(prefs).notifications;
|
|
287
298
|
}
|
|
288
299
|
|
|
300
|
+
/**
|
|
301
|
+
* Should the LAN engine run? The file's answer, unless the machine said no.
|
|
302
|
+
*
|
|
303
|
+
* AGENTS_DECK_NO_LAN=1 wins for the reason AGENTS_DECK_NO_NOTIFY does above:
|
|
304
|
+
* whoever launched the deck is making a claim about the machine, and a page
|
|
305
|
+
* posting to /api/prefs is not entitled to overrule it. It earns its keep twice
|
|
306
|
+
* over now that the feature is on by default — it is also how this repo's own
|
|
307
|
+
* suite keeps the decks it boots off the network it is being run on.
|
|
308
|
+
*/
|
|
309
|
+
export function lanEnabled(prefs, env = process.env) {
|
|
310
|
+
if (env.AGENTS_DECK_NO_LAN === "1") return false;
|
|
311
|
+
return normalise(prefs).lan.enabled;
|
|
312
|
+
}
|
|
313
|
+
|
|
289
314
|
/**
|
|
290
315
|
* Did the MACHINE veto this, as opposed to the person?
|
|
291
316
|
*
|
package/src/server/index.mjs
CHANGED
|
@@ -32,7 +32,7 @@ import { createActivity } from "./activity.mjs";
|
|
|
32
32
|
import { createOutputWatch } from "./output-watch.mjs";
|
|
33
33
|
import { AWAY_BOOT_GRACE_MS, AWAY_RECHECK_MS, AWAY_TICK_MS, awayGate, awayUpdateStep } from "./auto-update.mjs";
|
|
34
34
|
import { createPresence } from "./presence.mjs";
|
|
35
|
-
import { DEFAULTS as PREF_DEFAULTS, cleanAlias, isAliasKey, notificationsOn, notificationsVetoed, publicPrefs, readPrefs, writePrefs } from "./deck-prefs.mjs";
|
|
35
|
+
import { DEFAULTS as PREF_DEFAULTS, cleanAlias, isAliasKey, lanEnabled, notificationsOn, notificationsVetoed, publicPrefs, readPrefs, writePrefs } from "./deck-prefs.mjs";
|
|
36
36
|
import { createEngine, defaultName } from "./lan-engine.mjs";
|
|
37
37
|
import { aboutThisDeck } from "./lan-about.mjs";
|
|
38
38
|
import { PROBE_PS, localAliases, reachability, readProbe } from "./lan-reach.mjs";
|
|
@@ -3451,7 +3451,10 @@ async function applyLanPrefs() {
|
|
|
3451
3451
|
const lan = _prefs?.lan ?? {};
|
|
3452
3452
|
try {
|
|
3453
3453
|
await lanEngine.apply({
|
|
3454
|
-
|
|
3454
|
+
// The file's answer unless the machine said no: AGENTS_DECK_NO_LAN=1 is
|
|
3455
|
+
// how a launch script — or this repo's own test suite — keeps a deck off
|
|
3456
|
+
// the network now that the default is on.
|
|
3457
|
+
enabled: lanEnabled(_prefs),
|
|
3455
3458
|
name: lan.name || defaultName(),
|
|
3456
3459
|
secret: lan.secret || "",
|
|
3457
3460
|
shared: Array.isArray(lan.shared) ? lan.shared : [],
|