Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,31 @@ concurrency:
cancel-in-progress: true

jobs:
nix:
name: nix (${{ matrix.system }})
runs-on: ${{ matrix.runner }}
permissions:
contents: read
strategy:
fail-fast: false
matrix:
include:
- system: x86_64-linux
runner: ubuntu-latest
- system: aarch64-linux
runner: ubuntu-24.04-arm
- system: x86_64-darwin
runner: macos-15-intel
- system: aarch64-darwin
runner: macos-15
steps:
- uses: actions/checkout@v6.0.3

- uses: cachix/install-nix-action@v31

- name: build
run: nix build

check:
name: ${{ matrix.name }}
runs-on: ubuntu-latest
Expand Down
74 changes: 74 additions & 0 deletions .github/workflows/nix-pnpm-deps.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
name: nix pnpm dependency hash

on:
pull_request:

permissions:
contents: read
pull-requests: write

concurrency:
group: nix-pnpm-dependency-hash-${{ github.event.pull_request.number }}
cancel-in-progress: true

jobs:
check:
name: check nix package inputs
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v6.0.3

- name: install nix
uses: cachix/install-nix-action@v31

- id: update
name: calculate nix package fixes
shell: bash
run: |
submodule_rev=$(git ls-tree HEAD upstream-t3code | awk '{ print $3 }')
sed -i -E \
"s#github:pingdotgg/t3code/[0-9a-f]{40}#github:pingdotgg/t3code/$submodule_rev#" \
flake.nix
grep -Fq "url = \"github:pingdotgg/t3code/$submodule_rev\";" flake.nix
nix flake update upstream-t3code

nix run github:Mic92/nix-update/cf68051e7b7e08de6c707484cdcd1a53feb48e05 -- \
t3code-cli \
--flake \
--version=skip \
--override-filename nix/package.nix \
--build

if git diff --quiet -- flake.nix flake.lock nix/package.nix; then
echo "changed=false" >> "$GITHUB_OUTPUT"
else
echo "changed=true" >> "$GITHUB_OUTPUT"
{
echo 'The Nix source pin or pnpm dependency hash is stale. Apply this change to the pull request:'
echo
echo '```diff'
git diff -- flake.nix flake.lock nix/package.nix
echo '```'
} > "$RUNNER_TEMP/nix-pnpm-dependency-hash.md"
fi

- name: post proposed hash change
if: steps.update.outputs.changed == 'true'
uses: marocchino/sticky-pull-request-comment@v2
with:
header: nix-pnpm-dependency-hash
path: ${{ runner.temp }}/nix-pnpm-dependency-hash.md

- name: remove resolved hash comment
if: steps.update.outputs.changed == 'false'
uses: marocchino/sticky-pull-request-comment@v2
with:
header: nix-pnpm-dependency-hash
delete: true

- name: fail on dependency hash drift
if: steps.update.outputs.changed == 'true'
run: |
echo '::error::The Nix package inputs are stale. Apply the change from the pull request comment.'
exit 1
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ Install it with:
npx skills add tarik02-org/t3code-cli
```

## Nix

On NixOS or another system with Nix installed:

```sh
nix profile install github:tarik02-org/t3code-cli
```

## Authentication

`t3cli` stores multiple named auth environments in `~/.config/t3cli/config.json` (or `$XDG_CONFIG_HOME/t3cli/config.json`). Tokens are encrypted at rest with AES-256-GCM; the master key is stored in the OS keyring when available, otherwise in `~/.config/t3cli/key`.
Expand Down
62 changes: 62 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

54 changes: 54 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
description = "T3 Code CLI";

inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
nixpkgs-darwin.url = "github:NixOS/nixpkgs/nixpkgs-26.05-darwin";

upstream-t3code = {
url = "github:pingdotgg/t3code/3b72d17cbca691f0b64e6d4a10c9e349f42873a5";
flake = false;
};
};

outputs =
{
nixpkgs,
nixpkgs-darwin,
self,
upstream-t3code,
}:
let
systems = [
"x86_64-linux"
"aarch64-linux"
"x86_64-darwin"
"aarch64-darwin"
];
nixpkgsFor = system: if system == "x86_64-darwin" then nixpkgs-darwin else nixpkgs;
in
{
packages = nixpkgs.lib.genAttrs systems (
system:
let
pkgs = import (nixpkgsFor system) { inherit system; };
in
rec {
t3code-cli = pkgs.callPackage ./nix/package.nix {
src = self;
upstreamSrc = upstream-t3code;
};

default = t3code-cli;
}
);

formatter = nixpkgs.lib.genAttrs systems (
system:
let
pkgs = import (nixpkgsFor system) { inherit system; };
in
pkgs.nixfmt
);
};
}
93 changes: 93 additions & 0 deletions nix/package.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
{
autoPatchelfHook,
cacert,
fetchPnpmDeps,
installShellFiles,
lib,
libsecret,
makeWrapper,
nodejs_24,
pnpm_10,
pnpmConfigHook,
runCommand,
src,
stdenv,
upstreamSrc,
writableTmpDirAsHomeHook,
}:

let
nodejs = nodejs_24;
pnpm = pnpm_10;
version = (builtins.fromJSON (builtins.readFile "${src}/package.json")).version;
sourceWithUpstream = runCommand "t3code-cli-${version}-source" { } ''
cp --recursive --no-preserve=mode ${src} $out
chmod --recursive u+w $out
rm -rf $out/upstream-t3code
cp --recursive --no-preserve=mode ${upstreamSrc} $out/upstream-t3code
'';
in
stdenv.mkDerivation (finalAttrs: {
pname = "t3code-cli";
inherit version;
src = sourceWithUpstream;
strictDeps = true;

pnpmDeps = fetchPnpmDeps {
inherit (finalAttrs) pname version src;
inherit pnpm;
fetcherVersion = 4;
hash = "sha256-2bwrSxiSH8/S/JaB9aqNpNEmzLo5rSoIawIk8FONMMI=";
};

nativeBuildInputs = [
installShellFiles
makeWrapper
nodejs
pnpm
pnpmConfigHook
writableTmpDirAsHomeHook
]
++ lib.optional stdenv.hostPlatform.isLinux autoPatchelfHook;

buildInputs = lib.optional stdenv.hostPlatform.isLinux libsecret;

noAuditTmpdir = true;
SSL_CERT_FILE = "${cacert}/etc/ssl/certs/ca-bundle.crt";

buildPhase = ''
runHook preBuild
pnpm build
runHook postBuild
'';

installPhase = ''
runHook preInstall

app="$out/libexec/t3code-cli"
mkdir -p "$out/bin"
pnpm --filter t3code-cli --config.inject-workspace-packages=true \
deploy --prod --offline "$app"
makeWrapper ${lib.getExe nodejs} "$out/bin/t3cli" \
--add-flags "$app/dist/bin.js"
installShellCompletion --cmd t3cli \
--bash <($out/bin/t3cli --completions bash) \
--fish <($out/bin/t3cli --completions fish) \
--zsh <($out/bin/t3cli --completions zsh)

runHook postInstall
'';

meta = {
description = "Non-interactive CLI for T3 Code";
homepage = "https://github.com/tarik02-org/t3code-cli";
license = lib.licenses.mit;
mainProgram = "t3cli";
platforms = [
"x86_64-linux"
"aarch64-linux"
"x86_64-darwin"
"aarch64-darwin"
];
};
})
Loading