@promptctl/cc-candybar 1.34.1 → 1.36.0
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/index.mjs +88 -88
- package/package.json +5 -5
- package/src/check.ts +5 -0
- package/src/config/default-dsl-config.ts +59 -0
- package/src/config/dsl-loader.ts +20 -1
- package/src/config/edit-chrome.ts +62 -22
- package/src/config/loader/cross-ref.ts +44 -0
- package/src/config/loader/edit-mode.ts +14 -0
- package/src/config/settings-menu.ts +373 -0
- package/src/daemon/client.ts +6 -3
- package/src/daemon/protocol.ts +62 -5
- package/src/daemon/render-payload.ts +120 -0
- package/src/daemon/server.ts +13 -8
- package/src/index.ts +34 -4
package/src/daemon/server.ts
CHANGED
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
PROTOCOL_VERSION,
|
|
39
39
|
encodeFrame,
|
|
40
40
|
makeFrameReader,
|
|
41
|
-
|
|
41
|
+
parseClientHints,
|
|
42
42
|
} from "./protocol";
|
|
43
43
|
import type { Request, Response } from "./protocol";
|
|
44
44
|
import { GitDataProvider } from "./cache/git";
|
|
@@ -836,17 +836,21 @@ async function handleRequest(req: Request): Promise<HandledRequest> {
|
|
|
836
836
|
req.cwd,
|
|
837
837
|
sessionConfigFile,
|
|
838
838
|
);
|
|
839
|
-
// [LAW:
|
|
840
|
-
//
|
|
841
|
-
//
|
|
842
|
-
//
|
|
843
|
-
//
|
|
844
|
-
//
|
|
839
|
+
// [LAW:parse-dont-validate] The ONE checkpoint for everything the client
|
|
840
|
+
// observed and the daemon cannot. Raw `req.*` hint fields are not read
|
|
841
|
+
// past this line; `hints` is the stamped type the render path consumes.
|
|
842
|
+
//
|
|
843
|
+
// [LAW:single-enforcer] Every hint is captured client-side because the
|
|
844
|
+
// daemon is detached and shared: its env answers for whichever shell
|
|
845
|
+
// spawned it. We do NOT consult getTerminalWidth's env/stderr fallbacks
|
|
846
|
+
// for width, and we do NOT consult SSH_* for remoteness — both would
|
|
847
|
+
// describe a different session than the one being rendered.
|
|
845
848
|
// [LAW:one-source-of-truth] Both branches feed raw cols through
|
|
846
849
|
// applyClaudeCodeReserve, so `width` always means "usable cells
|
|
847
850
|
// post-reserve" with no semantic split between wire-supplied and
|
|
848
851
|
// fallback values.
|
|
849
|
-
const
|
|
852
|
+
const hints = parseClientHints(req);
|
|
853
|
+
const termCols = hints.termCols;
|
|
850
854
|
const width = applyClaudeCodeReserve(termCols ?? DEFAULT_TERMINAL_WIDTH);
|
|
851
855
|
const renderOpts: BuildLineOptions = { ...RENDER_OPTS_BASE, width };
|
|
852
856
|
// [LAW:dataflow-not-control-flow] Two outcomes fall out of one rule:
|
|
@@ -926,6 +930,7 @@ async function handleRequest(req: Request): Promise<HandledRequest> {
|
|
|
926
930
|
req.cwd,
|
|
927
931
|
entry.state.neededInputPaths,
|
|
928
932
|
effective,
|
|
933
|
+
hints,
|
|
929
934
|
);
|
|
930
935
|
// [LAW:one-source-of-truth][LAW:dataflow-not-control-flow] basePalette
|
|
931
936
|
// is derived from the same effective theme resolved above — so a theme
|
package/src/index.ts
CHANGED
|
@@ -36,6 +36,33 @@ function detectTermCols(): number | undefined {
|
|
|
36
36
|
return undefined;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
// The env vars an SSH login shell inherits from sshd. Any one of them present
|
|
40
|
+
// and non-empty means this session arrived over the network.
|
|
41
|
+
//
|
|
42
|
+
// [LAW:one-source-of-truth] This vocabulary is mirrored by the Rust client
|
|
43
|
+
// (rust-client/src/main.rs) and diffed by scripts/check-protocol.mjs, which
|
|
44
|
+
// anchors on the declaration below — keep it a named const holding string
|
|
45
|
+
// literals, or repoint the CHECKS row in the same commit. Both runtimes must
|
|
46
|
+
// agree on what "SSH" means or the fast path and the fallback path would
|
|
47
|
+
// disagree about the same session.
|
|
48
|
+
//
|
|
49
|
+
// All three are checked, not just SSH_CONNECTION: SSH_CLIENT is what older
|
|
50
|
+
// sshd builds (and the user's git-taculous zsh theme) key on, and SSH_TTY is
|
|
51
|
+
// the one that survives some `sudo` env_keep policies. Extra names can only
|
|
52
|
+
// widen recall of a fact that is otherwise reported as a plain `false`.
|
|
53
|
+
const SSH_ENV_VARS = ["SSH_CONNECTION", "SSH_CLIENT", "SSH_TTY"] as const;
|
|
54
|
+
|
|
55
|
+
// [LAW:dataflow-not-control-flow] A fold over the vocabulary, not a chain of
|
|
56
|
+
// ifs — adding a name is a data edit.
|
|
57
|
+
//
|
|
58
|
+
// Unlike detectTermCols this is TOTAL: the client reads its own environment, so
|
|
59
|
+
// "no SSH var set" is the affirmative answer "local", never a failure to
|
|
60
|
+
// determine. It therefore always reports, and the daemon reads an ABSENT `ssh`
|
|
61
|
+
// hint as "this client is too old to answer" rather than as "local".
|
|
62
|
+
function detectSsh(): boolean {
|
|
63
|
+
return SSH_ENV_VARS.some((name) => (process.env[name] ?? "") !== "");
|
|
64
|
+
}
|
|
65
|
+
|
|
39
66
|
function showHelpText(): void {
|
|
40
67
|
console.log(HELP_TEXT);
|
|
41
68
|
}
|
|
@@ -134,15 +161,18 @@ echo '{"session_id":"test-session","workspace":{"project_dir":"/path/to/project"
|
|
|
134
161
|
// caches). On daemon miss we spawn detached and emit empty output; the
|
|
135
162
|
// next status-line refresh hits the warm daemon and renders for real.
|
|
136
163
|
//
|
|
137
|
-
// [LAW:single-enforcer]
|
|
164
|
+
// [LAW:single-enforcer] Client hints are captured here, in the user's
|
|
138
165
|
// shell environment, then trusted by the daemon. The daemon's own env
|
|
139
|
-
// reflects whichever shell launched it minutes/hours ago, so it can
|
|
140
|
-
// measure the active terminal
|
|
166
|
+
// reflects whichever shell launched it minutes/hours ago, so it can
|
|
167
|
+
// measure neither the active terminal nor whether THIS session came in
|
|
168
|
+
// over SSH — only the live client can. One daemon serves a local session
|
|
169
|
+
// and an SSH session at the same time, so the answer genuinely differs per
|
|
170
|
+
// request.
|
|
141
171
|
const outcome = await tryRenderViaDaemon(
|
|
142
172
|
hookData,
|
|
143
173
|
process.argv,
|
|
144
174
|
process.cwd(),
|
|
145
|
-
detectTermCols(),
|
|
175
|
+
{ termCols: detectTermCols(), ssh: detectSsh() },
|
|
146
176
|
);
|
|
147
177
|
// [LAW:types-are-the-program] Three variants, one per outcome kind. The
|
|
148
178
|
// "kick on every failure" pattern was the load-bearing half of the
|