mirror of
https://github.com/nix-community/home-manager.git
synced 2026-06-05 21:02:51 +00:00
`literalExpression` is intended just to signify code that needs to stay a string that gets represented exactly as-is for docs. It has been misused heavily and people get confused repeatedly on when or not to use it because of the rampant misuse.
190 lines
5.4 KiB
Nix
190 lines
5.4 KiB
Nix
{
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
...
|
|
}:
|
|
let
|
|
inherit (lib)
|
|
literalExpression
|
|
mkIf
|
|
mkMerge
|
|
mkOption
|
|
types
|
|
;
|
|
|
|
cfg = config.programs.t3code;
|
|
jsonFormat = pkgs.formats.json { };
|
|
json5 = pkgs.python3Packages.toPythonApplication pkgs.python3Packages.json5;
|
|
|
|
impureConfigMerger = empty: jqOperation: path: staticSettings: ''
|
|
mkdir -p "$(dirname -- ${lib.escapeShellArg path})"
|
|
if [ ! -e ${lib.escapeShellArg path} ]; then
|
|
echo ${lib.escapeShellArg empty} > ${lib.escapeShellArg path}
|
|
fi
|
|
dynamic="$(${lib.getExe json5} --as-json ${lib.escapeShellArg path})"
|
|
static="$(cat ${lib.escapeShellArg staticSettings})"
|
|
config="$(${lib.getExe pkgs.jq} -n ${lib.escapeShellArg jqOperation} --argjson dynamic "$dynamic" --argjson static "$static")"
|
|
printf '%s\n' "$config" > ${lib.escapeShellArg path}
|
|
unset config
|
|
'';
|
|
|
|
userDataDir = "${config.home.homeDirectory}/.t3/userdata";
|
|
in
|
|
{
|
|
meta.maintainers = [
|
|
lib.maintainers.iamanaws
|
|
];
|
|
|
|
options.programs.t3code = {
|
|
enable = lib.mkEnableOption "T3 Code, a minimal web GUI for coding agents";
|
|
|
|
package = mkOption {
|
|
type = types.nullOr types.package;
|
|
default = pkgs.t3code or null;
|
|
defaultText = literalExpression "pkgs.t3code";
|
|
description = ''
|
|
The t3code package to install.
|
|
'';
|
|
};
|
|
|
|
mutableUserSettings = mkOption {
|
|
type = types.bool;
|
|
default = true;
|
|
example = false;
|
|
description = ''
|
|
Whether user settings ({file}`settings.json`) can be updated by t3code.
|
|
'';
|
|
};
|
|
|
|
mutableKeybindings = mkOption {
|
|
type = types.bool;
|
|
default = true;
|
|
example = false;
|
|
description = ''
|
|
Whether user keybindings ({file}`keybindings.json`) can be updated by t3code.
|
|
'';
|
|
};
|
|
|
|
mutableClientSettings = mkOption {
|
|
type = types.bool;
|
|
default = true;
|
|
example = false;
|
|
description = ''
|
|
Whether client settings ({file}`client-settings.json`) can be updated by t3code.
|
|
'';
|
|
};
|
|
|
|
userSettings = mkOption {
|
|
inherit (jsonFormat) type;
|
|
default = { };
|
|
example = {
|
|
enableAssistantStreaming = true;
|
|
providerInstances = {
|
|
codex = {
|
|
driver = "codex";
|
|
enabled = true;
|
|
config = {
|
|
enabled = true;
|
|
binaryPath = "codex";
|
|
homePath = "";
|
|
shadowHomePath = "";
|
|
customModels = [ ];
|
|
};
|
|
};
|
|
};
|
|
};
|
|
description = ''
|
|
Configuration written to t3code's {file}`settings.json`.
|
|
'';
|
|
};
|
|
|
|
keybindings = mkOption {
|
|
inherit (jsonFormat) type;
|
|
default = [ ];
|
|
example = [
|
|
{
|
|
key = "mod+j";
|
|
command = "terminal.toggle";
|
|
}
|
|
{
|
|
key = "mod+d";
|
|
command = "terminal.split";
|
|
when = "terminalFocus";
|
|
}
|
|
{
|
|
key = "mod+d";
|
|
command = "diff.toggle";
|
|
when = "!terminalFocus";
|
|
}
|
|
];
|
|
description = ''
|
|
Configuration written to t3code's {file}`keybindings.json`.
|
|
'';
|
|
};
|
|
|
|
clientSettings = mkOption {
|
|
inherit (jsonFormat) type;
|
|
default = { };
|
|
example = {
|
|
settings = {
|
|
favorites = [
|
|
{
|
|
provider = "codex";
|
|
model = "gpt-5.5";
|
|
}
|
|
];
|
|
sidebarProjectGroupingMode = "repository";
|
|
timestampFormat = "locale";
|
|
};
|
|
};
|
|
description = ''
|
|
Configuration written to t3code's {file}`client-settings.json`.
|
|
'';
|
|
};
|
|
};
|
|
|
|
config = mkIf cfg.enable {
|
|
home.packages = mkIf (cfg.package != null) [ cfg.package ];
|
|
|
|
home.activation = mkMerge [
|
|
(mkIf (cfg.mutableUserSettings && cfg.userSettings != { }) {
|
|
t3codeSettingsActivation = lib.hm.dag.entryAfter [ "linkGeneration" ] (
|
|
impureConfigMerger "{}" "$dynamic * $static" "${userDataDir}/settings.json" (
|
|
jsonFormat.generate "t3code-user-settings" cfg.userSettings
|
|
)
|
|
);
|
|
})
|
|
(mkIf (cfg.mutableKeybindings && cfg.keybindings != [ ]) {
|
|
t3codeKeybindingsActivation = lib.hm.dag.entryAfter [ "linkGeneration" ] (
|
|
impureConfigMerger "[]"
|
|
"$dynamic + $static | group_by([.key, .when]) | map(reduce .[] as $item ({}; . * $item))"
|
|
"${userDataDir}/keybindings.json"
|
|
(jsonFormat.generate "t3code-user-keybindings" cfg.keybindings)
|
|
);
|
|
})
|
|
(mkIf (cfg.mutableClientSettings && cfg.clientSettings != { }) {
|
|
t3codeClientSettingsActivation = lib.hm.dag.entryAfter [ "linkGeneration" ] (
|
|
impureConfigMerger "{}" "$dynamic * $static" "${userDataDir}/client-settings.json" (
|
|
jsonFormat.generate "t3code-client-settings" cfg.clientSettings
|
|
)
|
|
);
|
|
})
|
|
];
|
|
|
|
home.file = mkMerge [
|
|
(mkIf (!cfg.mutableUserSettings && cfg.userSettings != { }) {
|
|
".t3/userdata/settings.json".source = jsonFormat.generate "t3code-user-settings" cfg.userSettings;
|
|
})
|
|
(mkIf (!cfg.mutableKeybindings && cfg.keybindings != [ ]) {
|
|
".t3/userdata/keybindings.json".source =
|
|
jsonFormat.generate "t3code-user-keybindings" cfg.keybindings;
|
|
})
|
|
(mkIf (!cfg.mutableClientSettings && cfg.clientSettings != { }) {
|
|
".t3/userdata/client-settings.json".source =
|
|
jsonFormat.generate "t3code-client-settings" cfg.clientSettings;
|
|
})
|
|
];
|
|
};
|
|
}
|