@svayam-opensource/prj 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,292 @@
1
+ #!/usr/bin/env bash
2
+ # install-deps.sh
3
+ # Hard-gate tool check for the Agentic Development Framework.
4
+ #
5
+ # Verifies the local toolchain is ready:
6
+ # Required: git, gh (authenticated), python3, pyyaml
7
+ # Optional: yq (python3+pyyaml covers all functionality)
8
+ #
9
+ # Auto-installs missing required tools (or hard-stops in --check mode).
10
+ #
11
+ # GitHub identity & access verification (which org / which user) lives
12
+ # in setup.sh, where the configured github_org is known. Run setup.sh
13
+ # next to configure your org; it will verify access against the values
14
+ # you provide.
15
+ #
16
+ # Supported platforms:
17
+ # - macOS (via Homebrew)
18
+ # - Ubuntu/Debian Linux (via apt)
19
+ # - RHEL/Fedora/CentOS (via dnf/yum)
20
+ # - Arch Linux (via pacman)
21
+ # - Alpine Linux (via apk)
22
+ # - Windows/WSL (treated as the underlying Linux distro)
23
+ # - Git Bash/Cygwin on Windows (limited — WSL strongly recommended)
24
+ #
25
+ # Usage:
26
+ # bash scripts/install-deps.sh # install missing required deps, then verify
27
+ # bash scripts/install-deps.sh --check # check only, do not install
28
+
29
+ set -euo pipefail
30
+
31
+ CHECK_ONLY=false
32
+ [[ "${1:-}" == "--check" ]] && CHECK_ONLY=true
33
+
34
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
35
+ REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
36
+ CONFIG="$REPO_ROOT/org-config.yaml"
37
+
38
+ # ── Output helpers ────────────────────────────────────────────────────────────
39
+
40
+ RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; DIM='\033[2m'; NC='\033[0m'
41
+ ok() { echo -e "${GREEN} ✓${NC} $*"; }
42
+ fail() { echo -e "${RED} ✗${NC} $*"; }
43
+ warn() { echo -e "${YELLOW} !${NC} $*"; }
44
+ info() { echo -e "${CYAN} →${NC} $*"; }
45
+ note() { echo -e "${DIM} $*${NC}"; }
46
+ hard_stop() { echo ""; echo -e "${RED}HARD STOP:${NC} $*" >&2; echo ""; exit 1; }
47
+
48
+ # ── OS / distro detection ─────────────────────────────────────────────────────
49
+
50
+ detect_os() {
51
+ OS=""
52
+ PKG_MGR=""
53
+ case "$(uname -s)" in
54
+ Darwin) OS="macos" ;;
55
+ Linux)
56
+ OS="linux"
57
+ if grep -qi microsoft /proc/version 2>/dev/null; then
58
+ warn "Running inside WSL — treating as Linux."
59
+ fi
60
+ if command -v apt-get &>/dev/null; then PKG_MGR="apt"
61
+ elif command -v dnf &>/dev/null; then PKG_MGR="dnf"
62
+ elif command -v yum &>/dev/null; then PKG_MGR="yum"
63
+ elif command -v pacman &>/dev/null; then PKG_MGR="pacman"
64
+ elif command -v apk &>/dev/null; then PKG_MGR="apk"
65
+ else PKG_MGR="unknown"
66
+ fi
67
+ ;;
68
+ MINGW*|CYGWIN*|MSYS*)
69
+ OS="windows-bash"
70
+ warn "Git Bash / Cygwin detected — WSL is strongly recommended."
71
+ PKG_MGR="winget"
72
+ ;;
73
+ *) OS="unknown" ;;
74
+ esac
75
+ }
76
+
77
+ # ── Installers ────────────────────────────────────────────────────────────────
78
+
79
+ install_brew() {
80
+ if ! command -v brew &>/dev/null; then
81
+ info "Installing Homebrew..."
82
+ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
83
+ fi
84
+ }
85
+
86
+ install_git() {
87
+ case "$OS-$PKG_MGR" in
88
+ macos-*) install_brew; brew install git ;;
89
+ linux-apt) sudo apt-get install -y git ;;
90
+ linux-dnf) sudo dnf install -y git ;;
91
+ linux-yum) sudo yum install -y git ;;
92
+ linux-pacman) sudo pacman -S --noconfirm git ;;
93
+ linux-apk) sudo apk add --no-cache git ;;
94
+ windows-bash-*) warn "Install Git for Windows from https://git-scm.com/download/win" ;;
95
+ *) warn "Could not auto-install git — install manually." ;;
96
+ esac
97
+ }
98
+
99
+ install_gh_binary() {
100
+ info "Downloading gh binary from GitHub releases..."
101
+ local GH_VERSION="2.49.2"
102
+ local ARCH=$(uname -m)
103
+ local ARCH_TAG
104
+ case "$ARCH" in
105
+ x86_64) ARCH_TAG="amd64" ;;
106
+ aarch64|arm64) ARCH_TAG="arm64" ;;
107
+ *) ARCH_TAG="amd64" ;;
108
+ esac
109
+ local BINARY_URL="https://github.com/cli/cli/releases/download/v${GH_VERSION}/gh_${GH_VERSION}_linux_${ARCH_TAG}.tar.gz"
110
+ local INSTALL_DIR="${HOME}/.local/bin"
111
+ mkdir -p "$INSTALL_DIR"
112
+ local TMP=$(mktemp -d)
113
+ curl -fsSL "$BINARY_URL" | tar -xz -C "$TMP"
114
+ cp "$TMP/gh_${GH_VERSION}_linux_${ARCH_TAG}/bin/gh" "$INSTALL_DIR/gh"
115
+ chmod +x "$INSTALL_DIR/gh"
116
+ rm -rf "$TMP"
117
+ if [[ ":$PATH:" != *":$INSTALL_DIR:"* ]]; then
118
+ warn "Add $INSTALL_DIR to your PATH:"
119
+ warn " echo 'export PATH=\"\$HOME/.local/bin:\$PATH\"' >> ~/.bashrc # or ~/.zshrc"
120
+ export PATH="$INSTALL_DIR:$PATH"
121
+ fi
122
+ }
123
+
124
+ install_gh() {
125
+ case "$OS-$PKG_MGR" in
126
+ macos-*)
127
+ install_brew; brew install gh
128
+ ;;
129
+ linux-apt)
130
+ curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \
131
+ | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg
132
+ echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \
133
+ | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null
134
+ sudo apt-get update -q
135
+ sudo apt-get install -y gh
136
+ ;;
137
+ linux-dnf)
138
+ sudo dnf install -y 'dnf-command(config-manager)'
139
+ sudo dnf config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.repo
140
+ sudo dnf install -y gh
141
+ ;;
142
+ linux-yum)
143
+ sudo yum-config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.repo
144
+ sudo yum install -y gh
145
+ ;;
146
+ linux-pacman) sudo pacman -S --noconfirm github-cli ;;
147
+ linux-apk) install_gh_binary ;;
148
+ linux-unknown) install_gh_binary ;;
149
+ windows-bash-*) warn "Install GitHub CLI from https://cli.github.com or: winget install GitHub.cli" ;;
150
+ *) warn "Could not auto-install gh — see https://cli.github.com" ;;
151
+ esac
152
+ }
153
+
154
+ install_python3() {
155
+ case "$OS-$PKG_MGR" in
156
+ macos-*) install_brew; brew install python3 ;;
157
+ linux-apt) sudo apt-get install -y python3 python3-pip ;;
158
+ linux-dnf) sudo dnf install -y python3 python3-pip ;;
159
+ linux-yum) sudo yum install -y python3 python3-pip ;;
160
+ linux-pacman) sudo pacman -S --noconfirm python python-pip ;;
161
+ linux-apk) sudo apk add --no-cache python3 py3-pip ;;
162
+ *) warn "Install python3 manually from https://python.org" ;;
163
+ esac
164
+ }
165
+
166
+ install_pyyaml() {
167
+ if python3 -c "import yaml" &>/dev/null; then
168
+ return 0
169
+ fi
170
+ info "Installing PyYAML..."
171
+ case "$OS-$PKG_MGR" in
172
+ macos-*)
173
+ pip3 install --break-system-packages pyyaml \
174
+ || { warn "pip3 failed — trying brew pyyaml..."; brew install pyyaml 2>/dev/null || true; }
175
+ ;;
176
+ linux-apt)
177
+ sudo apt-get install -y python3-yaml 2>/dev/null \
178
+ || pip3 install --user pyyaml
179
+ ;;
180
+ linux-dnf)
181
+ sudo dnf install -y python3-pyyaml 2>/dev/null \
182
+ || pip3 install --user pyyaml
183
+ ;;
184
+ linux-yum)
185
+ sudo yum install -y python3-pyyaml 2>/dev/null \
186
+ || pip3 install --user pyyaml
187
+ ;;
188
+ linux-pacman) sudo pacman -S --noconfirm python-yaml ;;
189
+ linux-apk) sudo apk add --no-cache py3-yaml ;;
190
+ *)
191
+ pip3 install --user pyyaml \
192
+ || warn "Could not install PyYAML — install manually: pip3 install --user pyyaml"
193
+ ;;
194
+ esac
195
+ }
196
+
197
+ # ── Phase 1: Required + optional tool checks ─────────────────────────────────
198
+
199
+ echo ""
200
+ echo "Agentic Development Framework — Environment Check"
201
+ echo "=================================================="
202
+ detect_os
203
+ echo " OS: $OS"
204
+ echo " Pkg manager: ${PKG_MGR:-n/a}"
205
+ echo ""
206
+ echo "Tools:"
207
+
208
+ REQUIRED=(git gh python3)
209
+ MISSING_REQUIRED=()
210
+
211
+ for dep in "${REQUIRED[@]}"; do
212
+ if command -v "$dep" &>/dev/null; then
213
+ ok "$dep ($(command -v "$dep"))"
214
+ else
215
+ fail "$dep — required, not found"
216
+ MISSING_REQUIRED+=("$dep")
217
+ fi
218
+ done
219
+
220
+ # pyyaml as a python3 module
221
+ if command -v python3 &>/dev/null && python3 -c "import yaml" &>/dev/null; then
222
+ ok "pyyaml (python3 module)"
223
+ elif command -v python3 &>/dev/null; then
224
+ fail "pyyaml — required python3 module, not found"
225
+ MISSING_REQUIRED+=("pyyaml")
226
+ fi
227
+
228
+ # yq is optional — python3 + pyyaml covers all functionality
229
+ if command -v yq &>/dev/null; then
230
+ ok "yq ($(command -v yq)) ${DIM}[optional]${NC}"
231
+ else
232
+ info "yq not installed ${DIM}[optional — python3 + pyyaml covers all functionality]${NC}"
233
+ fi
234
+
235
+ echo ""
236
+
237
+ # Auto-install required if not in --check mode
238
+ if [[ ${#MISSING_REQUIRED[@]} -gt 0 ]]; then
239
+ if $CHECK_ONLY; then
240
+ hard_stop "Missing required: ${MISSING_REQUIRED[*]}. Run without --check to attempt auto-install."
241
+ fi
242
+ echo "Installing missing required tools: ${MISSING_REQUIRED[*]}"
243
+ echo ""
244
+ for dep in "${MISSING_REQUIRED[@]}"; do
245
+ info "Installing $dep..."
246
+ case "$dep" in
247
+ git) install_git ;;
248
+ gh) install_gh ;;
249
+ python3) install_python3 ;;
250
+ pyyaml) install_pyyaml ;;
251
+ esac
252
+ done
253
+
254
+ # Re-verify
255
+ echo ""
256
+ echo "Re-verifying..."
257
+ ALL_OK=true
258
+ for dep in "${MISSING_REQUIRED[@]}"; do
259
+ if [[ "$dep" == "pyyaml" ]]; then
260
+ if python3 -c "import yaml" &>/dev/null; then
261
+ ok "pyyaml (python3 module)"
262
+ else
263
+ fail "pyyaml — still not installed"
264
+ ALL_OK=false
265
+ fi
266
+ else
267
+ if command -v "$dep" &>/dev/null; then
268
+ ok "$dep ($(command -v "$dep"))"
269
+ else
270
+ fail "$dep — still not installed"
271
+ ALL_OK=false
272
+ fi
273
+ fi
274
+ done
275
+ $ALL_OK || hard_stop "Required tools could not be installed. See warnings above; install manually then re-run."
276
+ echo ""
277
+ fi
278
+
279
+ # ── gh authentication ─────────────────────────────────────────────────────────
280
+
281
+ echo "GitHub CLI auth:"
282
+ if ! gh auth status &>/dev/null; then
283
+ fail "gh CLI is not authenticated"
284
+ hard_stop "Run: gh auth login"
285
+ fi
286
+ ok "gh authenticated"
287
+
288
+ echo ""
289
+ ok "All required tools installed and gh authenticated."
290
+ echo ""
291
+ echo "Next: bash setup.sh (configure for your org and verify GitHub access)"
292
+ echo ""
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env bash
2
+ # Script: join
3
+ # Purpose: Set up an authorized member's OWN per-project workspace on an existing
4
+ # active/paused project. No new NNN, no change to assigned_to or
5
+ # seeded_by — this is how a teammate gets a local working copy under
6
+ # the per-task / team-ownership model (POL-047).
7
+ # Usage: bash join.sh <project_id>
8
+ # Compliance: authorization via is_authorized (assigned_to individual or team).
9
+
10
+ set -euo pipefail
11
+ source "$(dirname "$0")/lib.sh"
12
+ load_config
13
+
14
+ PROJECT_ID="${1:-}"
15
+ [[ -n "$PROJECT_ID" ]] || hard_stop "Usage: $0 <project_id>"
16
+
17
+ BRANCH=$(project_branch_for_id "$PROJECT_ID")
18
+ WORK_ROOT="$(project_work_root "$PROJECT_ID")"
19
+ ORG_GOV_DIR="$(org_gov_clone "$PROJECT_ID")"
20
+ GOV_REMOTE_URL=$(git -C "$REPO_ROOT" remote get-url origin 2>/dev/null || echo "")
21
+ [[ -n "$GOV_REMOTE_URL" ]] || hard_stop "No 'origin' remote on the governance repo."
22
+
23
+ echo "=== join: $PROJECT_ID"
24
+ echo " Branch: $BRANCH"
25
+ echo ""
26
+
27
+ mkdir -p "$WORK_ROOT"
28
+
29
+ # ── 1. Per-project ORG GOVERNANCE worktree (carries the project branch + manifest) ──
30
+ # ADR-0001 Phase 2: a worktree of one shared base clone, not a full per-project
31
+ # clone. ensure_repo_worktree is backward compatible with an existing clone.
32
+ info "Setting up ORG GOVERNANCE worktree → $ORG_GOV_DIR ('$BRANCH')..."
33
+ ensure_repo_worktree "$GOV_REMOTE_URL" "$ORG_GOV_DIR" "$BRANCH" \
34
+ || hard_stop "Could not set up the governance worktree for '$BRANCH' — has $PROJECT_ID been seeded and pushed?"
35
+
36
+ # Carry the joining developer's git identity into the per-project workspace so
37
+ # commits + C01 authorization here reflect them, not the ambient global.
38
+ set_clone_identity "$ORG_GOV_DIR"
39
+
40
+ PROJECT_YAML="$ORG_GOV_DIR/projects/$PROJECT_ID/project.yaml"
41
+ [[ -f "$PROJECT_YAML" ]] || hard_stop "project.yaml not found on branch '$BRANCH'."
42
+
43
+ # ── 2. Authorization + status (per-task / team model) ──
44
+ ASSIGNED_TO=$(yaml_get "$PROJECT_YAML" "assigned_to") # display/audit cache
45
+ GH_PROJECT=$(yaml_get "$PROJECT_YAML" "github_project")
46
+ is_authorized_for_project "$GH_PROJECT" "$ASSIGNED_TO" \
47
+ || hard_stop "You are not authorized to join '$PROJECT_ID' — you need write access to its GitHub Project ($GH_PROJECT)."
48
+ require_any_project_status "$PROJECT_YAML" "active" "paused"
49
+
50
+ # ── 3. Code-repo worktrees on the project branch ──
51
+ while IFS= read -r repo_url; do
52
+ [[ -z "$repo_url" || "$repo_url" == "~" ]] && continue
53
+ REPO_NAME=$(get_repo_name "$repo_url")
54
+ REPO_DIR="$(repo_clone_dir "$PROJECT_ID" "$REPO_NAME")"
55
+ info "Setting up $REPO_NAME worktree → $REPO_DIR ('$BRANCH')..."
56
+ if ensure_repo_worktree "$repo_url" "$REPO_DIR" "$BRANCH"; then
57
+ set_clone_identity "$REPO_DIR"
58
+ else
59
+ warn "Could not set up worktree for $REPO_NAME — skipping."
60
+ fi
61
+ done < <(get_project_repos "$PROJECT_YAML")
62
+
63
+ echo ""
64
+ echo "=== Joined $PROJECT_ID (branch '$BRANCH')."
65
+ echo " No NNN allocated; assigned_to / seeded_by unchanged."
66
+ echo ""
67
+ echo "── How to start work ──────────────────────────────────────────────────"
68
+ echo ""
69
+ echo " 1. Enter your per-project workspace:"
70
+ echo " cd $ORG_GOV_DIR"
71
+ echo " (governance clone on '$BRANCH'; code repos are under $WORK_ROOT/)"
72
+ echo ""
73
+ echo " 2. Read the start-up guidance already on this branch:"
74
+ echo " projects/$PROJECT_ID/agent.md — project entrypoint"
75
+ echo " CLAUDE.md / AGENTS.md — universal session-start protocol"
76
+ echo ""
77
+ echo " 3. Load the knowledge layers fresh (highest priority first):"
78
+ echo " knowledge/ (org-wide, read-only)"
79
+ echo " projects/$PROJECT_ID/knowledge/ (this project)"
80
+ echo " <repo>/knowledge/ (each code repo)"
81
+ echo " $AGENT_WORK_ROOT/preferences/<your-gh-login>.md (your preferences)"
82
+ echo ""
83
+ echo " 4. Confirm authorization: you have write access to the project's GitHub"
84
+ echo " Project board (project status must be active or paused)."
85
+ echo ""
86
+ echo " 5. Claim work — open a task sub-branch for a board issue:"
87
+ echo " ./prj task <issue-url> (or run ./prj start)"
88
+ echo ""
89
+ echo " Coordinate via the shared '$BRANCH' branch; close is run once by any member."