aboutsummaryrefslogtreecommitdiffstats
path: root/examples/tools/project.sh
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-10-19 11:49:06 +0200
committerDanilo M. <danix@danix.xyz>2026-10-19 11:49:06 +0200
commita150177a95ab576532559a1d8bf97d1cb17086e4 (patch)
treeb9631753be42c909963f443f5a4ed76e2f1bd4bc /examples/tools/project.sh
parent18a589cb4ad8f42e5190318fd1b912abf017ea0d (diff)
downloaddesktop-assistant-a150177a95ab576532559a1d8bf97d1cb17086e4.tar.gz
desktop-assistant-a150177a95ab576532559a1d8bf97d1cb17086e4.zip
project tool: start a new project and open an agent on it
project.sh makes a folder in ~/Programming/GIT with AGENTS.md, CLAUDE.md, README.md and LICENSE (GPLv2 only, GPLv2+, GPLv3 or MIT, texts shipped in licenses/), commits it signed, and opens Claude Code or opencode in a kitty tab, or a new window when no kitty listens. The tool description asks the model to confirm before calling. Check: test-project.sh. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'examples/tools/project.sh')
-rwxr-xr-xexamples/tools/project.sh137
1 files changed, 137 insertions, 0 deletions
diff --git a/examples/tools/project.sh b/examples/tools/project.sh
new file mode 100755
index 0000000..d8f7538
--- /dev/null
+++ b/examples/tools/project.sh
@@ -0,0 +1,137 @@
+#!/bin/bash
+# desktop-assistant tool: start a new project.
+# Copyright (C) 2026 Danilo M. <danix@danix.xyz>
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 as published
+# by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# project.sh <name> <license> <description> [claude|opencode]: a folder in
+# ~/Programming/GIT with AGENTS.md, CLAUDE.md, README.md and LICENSE, a
+# signed first commit, then a kitty tab running the agent there. Check:
+# test-project.sh.
+
+set -uo pipefail
+
+name=${1:-}
+license=${2:-}
+desc=${3:-}
+agent=${4:-claude}
+root=${PROJECTS_DIR:-$HOME/Programming/GIT}
+kitty=${KITTY:-kitty}
+here=$(dirname "$(readlink -f "$0")")
+year=$(date +%Y)
+author="Danilo M. <danix@danix.xyz>"
+
+[[ $name =~ ^[a-z0-9][a-z0-9._-]*$ ]] ||
+ { echo "name must be lowercase letters, digits, - _ . (not first), not: '$name'" >&2; exit 1; }
+case "${license:-gpl2}" in
+ gpl2) lic="GPLv2 only"; text=gpl-2.0.txt ;;
+ gpl2+) lic="GPLv2 or later"; text=gpl-2.0.txt ;;
+ gpl3) lic="GPLv3 only"; text=gpl-3.0.txt ;;
+ mit) lic="MIT"; text=mit.txt ;;
+ *) echo "license must be gpl2, gpl2+, gpl3 or mit, not: $license" >&2; exit 1 ;;
+esac
+[ -n "$desc" ] || { echo "description is empty" >&2; exit 1; }
+case "$agent" in
+ claude|opencode) ;;
+ *) echo "agent must be claude or opencode, not: $agent" >&2; exit 1 ;;
+esac
+dir=$root/$name
+[ -e "$dir" ] && { echo "$dir already exists" >&2; exit 1; }
+mkdir -p "$dir" && cd "$dir" || exit 1
+
+# Only MIT has its holder filled in: the GPL texts carry <year> in their
+# how-to-apply appendix, which must stay as published.
+if [ $text = mit.txt ]; then
+ sed "s/<year> <copyright holders>/$year $author/" "$here/licenses/$text" > LICENSE
+else
+ cp "$here/licenses/$text" LICENSE
+fi
+
+cat > CLAUDE.md <<'EOF'
+# CLAUDE.md
+
+This file is intentionally thin. AGENTS.md is the single source of truth for
+project guidance, shared across every agent tool. Edit AGENTS.md instead.
+
+@AGENTS.md
+EOF
+
+cat > AGENTS.md <<EOF
+# AGENTS.md
+
+Guidance for AI coding agents working in this repository.
+
+## What this is
+
+\`$name\`: $desc
+
+## Conventions
+
+- Placeholders only in code, docs, tests and commits.
+
+## Testing
+
+No test suite yet.
+
+## Repo facts
+
+- License: $lic (\`LICENSE\`).
+- Work directly on master.
+EOF
+
+cat > README.md <<EOF
+# $name
+
+$desc
+
+## License
+
+Copyright (C) $year $author
+
+$lic. See [LICENSE](LICENSE) for the full text.
+
+## Development Approach
+
+This project is developed using AI-assisted tools. Code is generated with the help of AI based on human-provided specifications, design decisions, and iterative feedback.
+
+All contributions are reviewed, tested, and curated by the maintainer before being included in the codebase. AI is used as a productivity and exploration tool, while human oversight remains central to all decisions.
+
+The goal is to combine the flexibility of AI-assisted development with standard open-source practices such as transparency, review, and accountability.
+EOF
+
+# Signing is never turned off: a cold cache brings up pinentry-qt, hence
+# the tool's 120 s timeout. A failed commit keeps the folder and says why.
+git init -q -b master && git add -A || exit 1
+if err=$(git commit -q -S -m "Initial commit" 2>&1); then
+ c="committed $(git rev-parse --short HEAD)"
+else
+ c="not committed: $(grep -m1 -E 'error|fatal' <<< "$err" || tail -1 <<< "$err")"
+fi
+
+# A tab in the running kitty if one listens (kitty-conf: listen_on
+# kitty-{kitty_pid}), else a new window.
+# ponytail: focuses some kitty window, not necessarily the one with the new
+# tab when several are open; match by kitty's window id if that bites.
+prompt="New project: $desc Fill in AGENTS.md and README.md from this, then wait."
+[ "$agent" = claude ] && run=(claude "$prompt") || run=(opencode --prompt "$prompt")
+how=window
+for s in $(ls -t "${XDG_RUNTIME_DIR:-/tmp}"/kitty-* 2>/dev/null); do
+ if "$kitty" @ --to "unix:$s" launch --type=tab --cwd="$dir" "${run[@]}" >/dev/null 2>&1; then
+ how=tab
+ hyprctl dispatch focuswindow class:kitty >/dev/null 2>&1
+ break
+ fi
+done
+[ $how = tab ] || setsid -f "$kitty" -d "$dir" "${run[@]}" >/dev/null 2>&1
+echo "created $dir ($lic), $c, opened $agent in a kitty $how"