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
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
{
"name": "taskyou-os",
"description": "Launch and manage AI agent teams on remote servers. Interactive setup walks you through everything — server provisioning, configuration, and deployment.",
"version": "1.3.0",
"version": "1.4.0",
"author": {
"name": "TaskYou"
},
Expand Down
5 changes: 3 additions & 2 deletions .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
{
"name": "taskyou-os",
"description": "Launch and manage AI agent teams on remote servers. Interactive setup walks you through everything — server provisioning, configuration, and deployment.",
"version": "1.3.0",
"version": "1.4.0",
"author": {
"name": "TaskYou"
},
"homepage": "https://github.com/taskyou/taskyou-os",
"repository": "https://github.com/taskyou/taskyou-os",
"license": "MIT",
"keywords": ["agents", "automation", "taskyou", "remote", "productivity"],
"commands": "./.claude/commands"
"commands": "./.claude/commands",
"hooks": "./hooks/hooks.json"
}
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ The taskyou-os plugin updates through the Claude Code marketplace. Run:

This pulls the latest version. Restart Claude Code afterward for changes to take effect.

**Tip: enable auto-update** so you get new features without checking manually. Auto-update is off by default for third-party marketplaces — turn it on via `/plugin` → **Marketplaces** → taskyou-os → *Enable auto-update*. Once on, Claude Code pulls new plugin versions for you and prompts you to `/reload-plugins`.

When a new plugin version adds a feature your existing GM doesn't have yet (e.g. the task-event channel), the GM will **proactively offer to enable it** at launch — just say yes, and it runs `/gm-doctor` for you. No need to track releases.

### Update a GM Installation

Run `/taskyou-os:doctor` from any directory. It checks and updates everything automatically:
Expand Down
41 changes: 41 additions & 0 deletions hooks/channel-nudge.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/usr/bin/env bash
# taskyou-os SessionStart hook (shipped by the plugin, so it reaches GMs that
# already exist once they update the plugin).
#
# Nudges a GM that predates the task-event channel to run /gm-doctor. It is:
# - SCOPED: only acts inside a rendered taskyou-os GM directory.
# - SELF-DISABLING: silent once the channel is deployed.
# Output: an `additionalContext` JSON object (exit 0) ONLY when the nudge
# applies; otherwise no output. The GM reads the note and surfaces it to the
# user conversationally.

set -uo pipefail

# SessionStart delivers JSON on stdin including `cwd`; prefer it, fall back to $PWD.
input="$(cat 2>/dev/null || true)"
cwd="$PWD"
if [ -n "$input" ] && command -v python3 >/dev/null 2>&1; then
parsed="$(printf '%s' "$input" | python3 -c 'import sys,json
try: print(json.load(sys.stdin).get("cwd",""))
except Exception: print("")' 2>/dev/null)"
[ -n "$parsed" ] && cwd="$parsed"
fi

# Only act in a taskyou-os GM directory (rendered config + wrapper present).
[ -f "$cwd/config.env" ] || exit 0
grep -q '^GM_ALIAS=' "$cwd/config.env" 2>/dev/null || exit 0
[ -f "$cwd/bin/ty-remote" ] || exit 0

# Channel already deployed? Stay silent.
if [ -f "$cwd/channel/taskyou-channel.ts" ] && [ -f "$cwd/.mcp.json" ]; then
exit 0
fi

note='This taskyou-os GM does not have the task-event channel installed yet. Push notifications — task completed/blocked events that arrive automatically in this session instead of via a polling agent — are available in this plugin version. Briefly let the user know, once, that they can enable it by running /gm-doctor (it deploys the channel and updates the launch alias; the GM must then be restarted). If the user declines, do not bring it up again this session.'

if command -v python3 >/dev/null 2>&1; then
printf '%s' "$note" | python3 -c 'import sys,json; print(json.dumps({"additionalContext": sys.stdin.read()}))'
else
printf '%s\n' "$note"
fi
exit 0
14 changes: 14 additions & 0 deletions hooks/hooks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "\"${CLAUDE_PLUGIN_ROOT}\"/hooks/channel-nudge.sh"
}
]
}
]
}
}
13 changes: 13 additions & 0 deletions qa/run-qa.sh
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,19 @@ grep -q 'The agents live on a remote server' "$GM_DIR/CLAUDE.md" && fail "CLAUDE
grep -q 'daemon is running on this machine' "$SANDBOX/local.log" && pass "checklist shows local daemon step" || fail "checklist not local-aware"
grep -q 'claude login' "$SANDBOX/local.log" && fail "checklist still tells you to 'claude login' on a server" || pass "checklist drops server-login steps"

# ── 1c. Plugin SessionStart nudge hook (existing-GM onboarding) ──────────────
echo; echo "[1c] plugin nudge hook — scoped + self-disabling"
NUDGE="$SRC/hooks/channel-nudge.sh"
# rendered GM HAS the channel → hook must stay silent
out=$(printf '{"cwd":"%s","source":"startup"}' "$GM_DIR" | bash "$NUDGE" 2>/dev/null)
[ -z "$out" ] && pass "nudge silent on a GM that already has the channel (self-disabling)" || fail "nudge fired on a channel-equipped GM"
# synthetic GM missing the channel → hook must nudge toward /gm-doctor
OLD="$SANDBOX/gm-old"; mkdir -p "$OLD/bin"; printf 'GM_ALIAS="x"\n' > "$OLD/config.env"; touch "$OLD/bin/ty-remote"
printf '{"cwd":"%s","source":"startup"}' "$OLD" | bash "$NUDGE" 2>/dev/null | grep -q 'gm-doctor' && pass "nudge fires on a GM missing the channel" || fail "nudge did not fire on a channel-less GM"
# non-GM dir → silent
out=$(printf '{"cwd":"%s","source":"startup"}' "$SANDBOX" | bash "$NUDGE" 2>/dev/null)
[ -z "$out" ] && pass "nudge silent outside a GM dir" || fail "nudge fired outside a GM dir"

# ── 2. Channel smoke test (PR #28's own test) ────────────────────────────────
echo; echo "[2] channel smoke-test (handshake + capabilities + tools)"
cp "$SRC/templates/channel/smoke-test.ts" "$GM_DIR/channel/smoke-test.ts"
Expand Down
Loading