Skip to content

Instantly share code, notes, and snippets.

View kballenegger's full-sized avatar

Kenneth Ballenegger kballenegger

View GitHub Profile
@kballenegger
kballenegger / flyertalk-modern-reskin.user.js
Created September 27, 2026 09:08
Compact FlyerTalk styling with warm cream backgrounds, fresh aqua and peach accents, refined quotes, and smaller edit notes.
// ==UserScript==
// @name FlyerTalk Modern ReSkin
// @description Compact FlyerTalk styling with warm cream backgrounds, fresh aqua and peach accents, refined quotes, and smaller edit notes.
// @version 1.0
// @match *://*.flyertalk.com/*
// @grant none
// ==/UserScript==
/* FlyerTalk Modern ReSkin — compact, weight-led forum design. */
(() => {
@kballenegger
kballenegger / google-workspace-live-collaboration.md
Created September 2, 2026 18:37
Minions skill for live collaboration in Google Docs, Sheets, and Slides
name google-workspace-live-collaboration
description Use when an agent has to work alongside a person inside a Google Doc, Sheet, or Slides deck over time instead of delivering a file once. Covers sharing safely, proving access before the wait starts, polling comment threads, guarding against clobbering concurrent human edits, deciding what to change without asking, and running the wait/wake loop on Minions.
license CC0-1.0

Live collaboration in a Google Workspace file

A one-shot agent creates a document, shares it, and stops. A live collaborator stays in the file while a person reads it: answering comments, applying small fixes, and asking before it reshapes anything. This skill is about the second mode.

@kballenegger
kballenegger / postmaster-zero-trust-email-proxy.md
Created March 20, 2026 16:31
How I Built a Zero-Trust Email Proxy for My OpenClaw Agent

How I Built a Zero-Trust Email Proxy for My OpenClaw Agent

By Kenneth Ballenegger


I wanted my OpenClaw agent to handle email — read it, triage it, draft replies. The obvious path is to hand it a Gmail OAuth token and let it call the API directly. I didn't do that.

Not because I don't trust the agent, but because that framing is wrong. The question isn't do I trust the agent — it's what rules should govern what it's allowed to do? Reading my inbox? Fine, always. Sending an email to an investor on my behalf? That needs my explicit sign-off. Permanently deleting messages? Never, under any circumstances.

@kballenegger
kballenegger / ihg-english.js
Last active January 3, 2023 06:55
Force IHG to speak English
// ==UserScript==
// @name IHG English
// @namespace http://tampermonkey.net/
// @version 0.1
// @description Force IHG site to English
// @author Kenneth Ballenegger
// @match https://www.ihg.com/hotels/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=kswizz.com
// @grant none
// ==/UserScript==
@kballenegger
kballenegger / google-flights-default-USD.js
Last active January 3, 2023 05:20
Force Google Flights to use USD
// ==UserScript==
// @name Google Flights Default USD
// @version 0.1
// @description Force Google Flights to use USD
// @author Kenneth Ballenegger
// @match https://www.google.com/flights/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=kswizz.com
// @grant none
// ==/UserScript==
@kballenegger
kballenegger / Crypto.gs
Created April 14, 2021 06:02
Crypto utilities for Google Sheets
function main() {
console.log(cryptoPrice("blockstack", "0.1"));
}
/**
* Sets a random number in P1
* @customfunction
*/
function refresh() {
@kballenegger
kballenegger / Code.gs
Created February 23, 2019 08:02
gc_distance Google Sheets Script
function _tester() {
Logger.log("New test run…")
var result = gc_distance('sfo', 'jfk');
Logger.log(result)
}
function location_of(airport) {
return data[airport.toUpperCase()];
}
@kballenegger
kballenegger / spotify-star-adder.rb
Created July 14, 2018 01:29
A script to add the currently playing track to a predefined playlist
#!/usr/bin/env ruby
require 'rubygems'
require 'rspotify'
require 'open3'
require 'uri'
require 'json'
# To use script
# 1/ Create an app at: https://developer.spotify.com/dashboard/applications
@kballenegger
kballenegger / shortest-string-path-substitutions.rb
Created July 8, 2017 02:00
Shortest path between strings only substitutions
Words = Set.new
File.open('/usr/share/dict/words') do |file|
file.each do |line|
Words.add(line.strip)
end
end
Alphabet = 'abcdefghijklmnopqrstuvwxyz'.split('')
def path(input, output)
@kballenegger
kballenegger / .pryrc
Created July 31, 2015 18:31
[WIP] Hide cluttery auto-generated Rails methods from Pry.
class ActiveRecord::Base
alias :old_methods :methods
def methods
old_methods.reject do |m|
m = m.to_s
m =~ /(=|_changed\?|_before_type_cast|_was|_change|_will_change!)$/ || \
m =~ /^_/
end
end
end