ai-summon 0.0.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.
- package/.claude/commands/speckit.analyze.md +184 -0
- package/.claude/commands/speckit.checklist.md +294 -0
- package/.claude/commands/speckit.clarify.md +177 -0
- package/.claude/commands/speckit.constitution.md +78 -0
- package/.claude/commands/speckit.implement.md +121 -0
- package/.claude/commands/speckit.plan.md +81 -0
- package/.claude/commands/speckit.specify.md +204 -0
- package/.claude/commands/speckit.tasks.md +108 -0
- package/.claude/settings.local.json +23 -0
- package/.prettierignore +5 -0
- package/.prettierrc.json +10 -0
- package/.specify/memory/constitution.md +72 -0
- package/.specify/scripts/bash/check-prerequisites.sh +166 -0
- package/.specify/scripts/bash/common.sh +113 -0
- package/.specify/scripts/bash/create-new-feature.sh +97 -0
- package/.specify/scripts/bash/setup-plan.sh +60 -0
- package/.specify/scripts/bash/update-agent-context.sh +738 -0
- package/.specify/templates/agent-file-template.md +28 -0
- package/.specify/templates/checklist-template.md +40 -0
- package/.specify/templates/plan-template.md +111 -0
- package/.specify/templates/spec-template.md +115 -0
- package/.specify/templates/tasks-template.md +250 -0
- package/CLAUDE.md +199 -0
- package/PRD.md +268 -0
- package/README.md +171 -0
- package/dist/ai-summon.d.ts +2 -0
- package/dist/ai-summon.js +73 -0
- package/dist/commands/ide/index.d.ts +3 -0
- package/dist/commands/ide/index.js +253 -0
- package/dist/commands/init.d.ts +4 -0
- package/dist/commands/init.js +55 -0
- package/dist/commands/url.d.ts +4 -0
- package/dist/commands/url.js +223 -0
- package/dist/types/index.d.ts +40 -0
- package/dist/types/index.js +1 -0
- package/dist/util.d.ts +16 -0
- package/dist/util.js +109 -0
- package/eslint.config.js +47 -0
- package/package.json +47 -0
- package/specs/001-cloud-login-feature/contracts/cloud-command.ts +82 -0
- package/specs/001-cloud-login-feature/contracts/config-service.ts +170 -0
- package/specs/001-cloud-login-feature/data-model.md +269 -0
- package/specs/001-cloud-login-feature/plan.md +91 -0
- package/specs/001-cloud-login-feature/quickstart.md +366 -0
- package/specs/001-cloud-login-feature/research.md +290 -0
- package/specs/001-cloud-login-feature/spec.md +195 -0
- package/specs/001-cloud-login-feature/tasks.md +235 -0
- package/specs/001-cloud-scp-command/contracts/cloud-scp-api.ts +402 -0
- package/specs/001-cloud-scp-command/data-model.md +424 -0
- package/specs/001-cloud-scp-command/plan.md +124 -0
- package/specs/001-cloud-scp-command/quickstart.md +536 -0
- package/specs/001-cloud-scp-command/research.md +345 -0
- package/specs/001-cloud-scp-command/spec.md +248 -0
- package/specs/001-cloud-scp-command/tasks.md +434 -0
- package/src/ai-summon.ts +88 -0
- package/src/commands/ide/index.ts +322 -0
- package/src/commands/init.ts +64 -0
- package/src/commands/url.ts +262 -0
- package/src/types/index.ts +49 -0
- package/src/util.ts +146 -0
- package/tsconfig.json +21 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Sync Impact Report:
|
|
3
|
+
- Version change: new → 1.0.0
|
|
4
|
+
- New constitution creation with 5 core principles
|
|
5
|
+
- Added sections: Technology Standards, Development Workflow
|
|
6
|
+
- Templates requiring updates: ✅ updated validation complete
|
|
7
|
+
- Follow-up TODOs: none
|
|
8
|
+
-->
|
|
9
|
+
|
|
10
|
+
# hsh19900502 Constitution
|
|
11
|
+
|
|
12
|
+
## Core Principles
|
|
13
|
+
|
|
14
|
+
### I. TypeScript-First Development
|
|
15
|
+
|
|
16
|
+
All code MUST be written in TypeScript with strict mode enabled. Every function, interface, and module must be fully typed. No `any` types allowed except for external library integrations where types are unavailable. ESM modules MUST be used throughout the codebase with proper import/export syntax.
|
|
17
|
+
|
|
18
|
+
_Rationale: Type safety prevents runtime errors and enables better tooling, refactoring, and code maintenance._
|
|
19
|
+
|
|
20
|
+
### II. Shell Integration via zx
|
|
21
|
+
|
|
22
|
+
All shell operations MUST use the zx library with template literals (`$` syntax). Direct shell command execution or child_process usage is prohibited. All shell operations MUST be async/await with proper error handling.
|
|
23
|
+
|
|
24
|
+
_Rationale: zx provides consistent shell execution across platforms with better error handling and TypeScript integration._
|
|
25
|
+
|
|
26
|
+
### III. Interactive CLI Design
|
|
27
|
+
|
|
28
|
+
Every user-facing operation MUST use inquirer prompts with validation, default values, and autocomplete where applicable. Commands should provide immediate feedback using chalk for colored output and ora for progress indicators. All user input must be validated before execution.
|
|
29
|
+
|
|
30
|
+
_Rationale: Interactive prompts reduce user errors and improve the developer experience by providing guidance and validation._
|
|
31
|
+
|
|
32
|
+
### IV. Modular Command Architecture
|
|
33
|
+
|
|
34
|
+
Commands MUST be organized by domain (git, mono, ide) in separate modules. Each command module exports specific functions that handle business logic. The main CLI file (hsh.ts) should only define command interfaces and delegate to domain modules.
|
|
35
|
+
|
|
36
|
+
_Rationale: Separation of concerns improves maintainability and allows for easier testing and extension of functionality._
|
|
37
|
+
|
|
38
|
+
### V. Yarn Package Management
|
|
39
|
+
|
|
40
|
+
All dependency management MUST use Yarn. Package.json scripts MUST follow established patterns: `build` for TypeScript compilation, `dev` for development with ts-node, `start` for running compiled code. Global installation must be supported via the `bin` field.
|
|
41
|
+
|
|
42
|
+
_Rationale: Yarn provides consistent dependency resolution and better performance. Standardized scripts ensure consistent development workflow._
|
|
43
|
+
|
|
44
|
+
## Technology Standards
|
|
45
|
+
|
|
46
|
+
**Language**: TypeScript 5.0+ with ES2020 target and ESNext modules
|
|
47
|
+
**Package Manager**: Yarn (required for all operations)
|
|
48
|
+
**Shell Integration**: zx library with `$` template literals
|
|
49
|
+
**CLI Framework**: Commander.js for command parsing
|
|
50
|
+
**User Interface**: inquirer for prompts, chalk for colors, ora for progress
|
|
51
|
+
**Build System**: TypeScript compiler with declaration files
|
|
52
|
+
**Module System**: ES modules with .js extensions in imports
|
|
53
|
+
**Project Structure**: src/ for source, dist/ for compiled output
|
|
54
|
+
|
|
55
|
+
## Development Workflow
|
|
56
|
+
|
|
57
|
+
**Build Process**: `yarn build` compiles TypeScript to dist/ with declarations
|
|
58
|
+
**Development**: `yarn dev` runs with ts-node for immediate feedback
|
|
59
|
+
**Installation**: `yarn build:install` for global testing
|
|
60
|
+
**Code Organization**: Domain-based modules in src/commands/
|
|
61
|
+
**Configuration**: External config files (~/hsh.config.json for IDE commands)
|
|
62
|
+
**Error Handling**: Chalk colors for user feedback, async/await for all operations
|
|
63
|
+
|
|
64
|
+
## Governance
|
|
65
|
+
|
|
66
|
+
This constitution supersedes all other development practices. All code changes must comply with these principles. Non-compliance requires explicit justification and approval through code review. The TypeScript compiler enforces type safety; builds that fail TypeScript compilation are not acceptable.
|
|
67
|
+
|
|
68
|
+
**Amendment Process**: Constitutional changes require documentation of rationale, impact assessment, and template synchronization. Breaking changes to core principles require major version bump.
|
|
69
|
+
|
|
70
|
+
**Compliance Review**: All PRs must verify TypeScript compilation, proper error handling, and adherence to modular architecture. Manual testing of CLI functionality is required for user-facing changes.
|
|
71
|
+
|
|
72
|
+
**Version**: 1.0.0 | **Ratified**: 2025-10-11 | **Last Amended**: 2025-10-11
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
# Consolidated prerequisite checking script
|
|
4
|
+
#
|
|
5
|
+
# This script provides unified prerequisite checking for Spec-Driven Development workflow.
|
|
6
|
+
# It replaces the functionality previously spread across multiple scripts.
|
|
7
|
+
#
|
|
8
|
+
# Usage: ./check-prerequisites.sh [OPTIONS]
|
|
9
|
+
#
|
|
10
|
+
# OPTIONS:
|
|
11
|
+
# --json Output in JSON format
|
|
12
|
+
# --require-tasks Require tasks.md to exist (for implementation phase)
|
|
13
|
+
# --include-tasks Include tasks.md in AVAILABLE_DOCS list
|
|
14
|
+
# --paths-only Only output path variables (no validation)
|
|
15
|
+
# --help, -h Show help message
|
|
16
|
+
#
|
|
17
|
+
# OUTPUTS:
|
|
18
|
+
# JSON mode: {"FEATURE_DIR":"...", "AVAILABLE_DOCS":["..."]}
|
|
19
|
+
# Text mode: FEATURE_DIR:... \n AVAILABLE_DOCS: \n ✓/✗ file.md
|
|
20
|
+
# Paths only: REPO_ROOT: ... \n BRANCH: ... \n FEATURE_DIR: ... etc.
|
|
21
|
+
|
|
22
|
+
set -e
|
|
23
|
+
|
|
24
|
+
# Parse command line arguments
|
|
25
|
+
JSON_MODE=false
|
|
26
|
+
REQUIRE_TASKS=false
|
|
27
|
+
INCLUDE_TASKS=false
|
|
28
|
+
PATHS_ONLY=false
|
|
29
|
+
|
|
30
|
+
for arg in "$@"; do
|
|
31
|
+
case "$arg" in
|
|
32
|
+
--json)
|
|
33
|
+
JSON_MODE=true
|
|
34
|
+
;;
|
|
35
|
+
--require-tasks)
|
|
36
|
+
REQUIRE_TASKS=true
|
|
37
|
+
;;
|
|
38
|
+
--include-tasks)
|
|
39
|
+
INCLUDE_TASKS=true
|
|
40
|
+
;;
|
|
41
|
+
--paths-only)
|
|
42
|
+
PATHS_ONLY=true
|
|
43
|
+
;;
|
|
44
|
+
--help|-h)
|
|
45
|
+
cat << 'EOF'
|
|
46
|
+
Usage: check-prerequisites.sh [OPTIONS]
|
|
47
|
+
|
|
48
|
+
Consolidated prerequisite checking for Spec-Driven Development workflow.
|
|
49
|
+
|
|
50
|
+
OPTIONS:
|
|
51
|
+
--json Output in JSON format
|
|
52
|
+
--require-tasks Require tasks.md to exist (for implementation phase)
|
|
53
|
+
--include-tasks Include tasks.md in AVAILABLE_DOCS list
|
|
54
|
+
--paths-only Only output path variables (no prerequisite validation)
|
|
55
|
+
--help, -h Show this help message
|
|
56
|
+
|
|
57
|
+
EXAMPLES:
|
|
58
|
+
# Check task prerequisites (plan.md required)
|
|
59
|
+
./check-prerequisites.sh --json
|
|
60
|
+
|
|
61
|
+
# Check implementation prerequisites (plan.md + tasks.md required)
|
|
62
|
+
./check-prerequisites.sh --json --require-tasks --include-tasks
|
|
63
|
+
|
|
64
|
+
# Get feature paths only (no validation)
|
|
65
|
+
./check-prerequisites.sh --paths-only
|
|
66
|
+
|
|
67
|
+
EOF
|
|
68
|
+
exit 0
|
|
69
|
+
;;
|
|
70
|
+
*)
|
|
71
|
+
echo "ERROR: Unknown option '$arg'. Use --help for usage information." >&2
|
|
72
|
+
exit 1
|
|
73
|
+
;;
|
|
74
|
+
esac
|
|
75
|
+
done
|
|
76
|
+
|
|
77
|
+
# Source common functions
|
|
78
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
79
|
+
source "$SCRIPT_DIR/common.sh"
|
|
80
|
+
|
|
81
|
+
# Get feature paths and validate branch
|
|
82
|
+
eval $(get_feature_paths)
|
|
83
|
+
check_feature_branch "$CURRENT_BRANCH" "$HAS_GIT" || exit 1
|
|
84
|
+
|
|
85
|
+
# If paths-only mode, output paths and exit (support JSON + paths-only combined)
|
|
86
|
+
if $PATHS_ONLY; then
|
|
87
|
+
if $JSON_MODE; then
|
|
88
|
+
# Minimal JSON paths payload (no validation performed)
|
|
89
|
+
printf '{"REPO_ROOT":"%s","BRANCH":"%s","FEATURE_DIR":"%s","FEATURE_SPEC":"%s","IMPL_PLAN":"%s","TASKS":"%s"}\n' \
|
|
90
|
+
"$REPO_ROOT" "$CURRENT_BRANCH" "$FEATURE_DIR" "$FEATURE_SPEC" "$IMPL_PLAN" "$TASKS"
|
|
91
|
+
else
|
|
92
|
+
echo "REPO_ROOT: $REPO_ROOT"
|
|
93
|
+
echo "BRANCH: $CURRENT_BRANCH"
|
|
94
|
+
echo "FEATURE_DIR: $FEATURE_DIR"
|
|
95
|
+
echo "FEATURE_SPEC: $FEATURE_SPEC"
|
|
96
|
+
echo "IMPL_PLAN: $IMPL_PLAN"
|
|
97
|
+
echo "TASKS: $TASKS"
|
|
98
|
+
fi
|
|
99
|
+
exit 0
|
|
100
|
+
fi
|
|
101
|
+
|
|
102
|
+
# Validate required directories and files
|
|
103
|
+
if [[ ! -d "$FEATURE_DIR" ]]; then
|
|
104
|
+
echo "ERROR: Feature directory not found: $FEATURE_DIR" >&2
|
|
105
|
+
echo "Run /speckit.specify first to create the feature structure." >&2
|
|
106
|
+
exit 1
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
if [[ ! -f "$IMPL_PLAN" ]]; then
|
|
110
|
+
echo "ERROR: plan.md not found in $FEATURE_DIR" >&2
|
|
111
|
+
echo "Run /speckit.plan first to create the implementation plan." >&2
|
|
112
|
+
exit 1
|
|
113
|
+
fi
|
|
114
|
+
|
|
115
|
+
# Check for tasks.md if required
|
|
116
|
+
if $REQUIRE_TASKS && [[ ! -f "$TASKS" ]]; then
|
|
117
|
+
echo "ERROR: tasks.md not found in $FEATURE_DIR" >&2
|
|
118
|
+
echo "Run /speckit.tasks first to create the task list." >&2
|
|
119
|
+
exit 1
|
|
120
|
+
fi
|
|
121
|
+
|
|
122
|
+
# Build list of available documents
|
|
123
|
+
docs=()
|
|
124
|
+
|
|
125
|
+
# Always check these optional docs
|
|
126
|
+
[[ -f "$RESEARCH" ]] && docs+=("research.md")
|
|
127
|
+
[[ -f "$DATA_MODEL" ]] && docs+=("data-model.md")
|
|
128
|
+
|
|
129
|
+
# Check contracts directory (only if it exists and has files)
|
|
130
|
+
if [[ -d "$CONTRACTS_DIR" ]] && [[ -n "$(ls -A "$CONTRACTS_DIR" 2>/dev/null)" ]]; then
|
|
131
|
+
docs+=("contracts/")
|
|
132
|
+
fi
|
|
133
|
+
|
|
134
|
+
[[ -f "$QUICKSTART" ]] && docs+=("quickstart.md")
|
|
135
|
+
|
|
136
|
+
# Include tasks.md if requested and it exists
|
|
137
|
+
if $INCLUDE_TASKS && [[ -f "$TASKS" ]]; then
|
|
138
|
+
docs+=("tasks.md")
|
|
139
|
+
fi
|
|
140
|
+
|
|
141
|
+
# Output results
|
|
142
|
+
if $JSON_MODE; then
|
|
143
|
+
# Build JSON array of documents
|
|
144
|
+
if [[ ${#docs[@]} -eq 0 ]]; then
|
|
145
|
+
json_docs="[]"
|
|
146
|
+
else
|
|
147
|
+
json_docs=$(printf '"%s",' "${docs[@]}")
|
|
148
|
+
json_docs="[${json_docs%,}]"
|
|
149
|
+
fi
|
|
150
|
+
|
|
151
|
+
printf '{"FEATURE_DIR":"%s","AVAILABLE_DOCS":%s}\n' "$FEATURE_DIR" "$json_docs"
|
|
152
|
+
else
|
|
153
|
+
# Text output
|
|
154
|
+
echo "FEATURE_DIR:$FEATURE_DIR"
|
|
155
|
+
echo "AVAILABLE_DOCS:"
|
|
156
|
+
|
|
157
|
+
# Show status of each potential document
|
|
158
|
+
check_file "$RESEARCH" "research.md"
|
|
159
|
+
check_file "$DATA_MODEL" "data-model.md"
|
|
160
|
+
check_dir "$CONTRACTS_DIR" "contracts/"
|
|
161
|
+
check_file "$QUICKSTART" "quickstart.md"
|
|
162
|
+
|
|
163
|
+
if $INCLUDE_TASKS; then
|
|
164
|
+
check_file "$TASKS" "tasks.md"
|
|
165
|
+
fi
|
|
166
|
+
fi
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Common functions and variables for all scripts
|
|
3
|
+
|
|
4
|
+
# Get repository root, with fallback for non-git repositories
|
|
5
|
+
get_repo_root() {
|
|
6
|
+
if git rev-parse --show-toplevel >/dev/null 2>&1; then
|
|
7
|
+
git rev-parse --show-toplevel
|
|
8
|
+
else
|
|
9
|
+
# Fall back to script location for non-git repos
|
|
10
|
+
local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
|
+
(cd "$script_dir/../../.." && pwd)
|
|
12
|
+
fi
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
# Get current branch, with fallback for non-git repositories
|
|
16
|
+
get_current_branch() {
|
|
17
|
+
# First check if SPECIFY_FEATURE environment variable is set
|
|
18
|
+
if [[ -n "${SPECIFY_FEATURE:-}" ]]; then
|
|
19
|
+
echo "$SPECIFY_FEATURE"
|
|
20
|
+
return
|
|
21
|
+
fi
|
|
22
|
+
|
|
23
|
+
# Then check git if available
|
|
24
|
+
if git rev-parse --abbrev-ref HEAD >/dev/null 2>&1; then
|
|
25
|
+
git rev-parse --abbrev-ref HEAD
|
|
26
|
+
return
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
# For non-git repos, try to find the latest feature directory
|
|
30
|
+
local repo_root=$(get_repo_root)
|
|
31
|
+
local specs_dir="$repo_root/specs"
|
|
32
|
+
|
|
33
|
+
if [[ -d "$specs_dir" ]]; then
|
|
34
|
+
local latest_feature=""
|
|
35
|
+
local highest=0
|
|
36
|
+
|
|
37
|
+
for dir in "$specs_dir"/*; do
|
|
38
|
+
if [[ -d "$dir" ]]; then
|
|
39
|
+
local dirname=$(basename "$dir")
|
|
40
|
+
if [[ "$dirname" =~ ^([0-9]{3})- ]]; then
|
|
41
|
+
local number=${BASH_REMATCH[1]}
|
|
42
|
+
number=$((10#$number))
|
|
43
|
+
if [[ "$number" -gt "$highest" ]]; then
|
|
44
|
+
highest=$number
|
|
45
|
+
latest_feature=$dirname
|
|
46
|
+
fi
|
|
47
|
+
fi
|
|
48
|
+
fi
|
|
49
|
+
done
|
|
50
|
+
|
|
51
|
+
if [[ -n "$latest_feature" ]]; then
|
|
52
|
+
echo "$latest_feature"
|
|
53
|
+
return
|
|
54
|
+
fi
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
echo "main" # Final fallback
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
# Check if we have git available
|
|
61
|
+
has_git() {
|
|
62
|
+
git rev-parse --show-toplevel >/dev/null 2>&1
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
check_feature_branch() {
|
|
66
|
+
local branch="$1"
|
|
67
|
+
local has_git_repo="$2"
|
|
68
|
+
|
|
69
|
+
# For non-git repos, we can't enforce branch naming but still provide output
|
|
70
|
+
if [[ "$has_git_repo" != "true" ]]; then
|
|
71
|
+
echo "[specify] Warning: Git repository not detected; skipped branch validation" >&2
|
|
72
|
+
return 0
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
if [[ ! "$branch" =~ ^[0-9]{3}- ]]; then
|
|
76
|
+
echo "ERROR: Not on a feature branch. Current branch: $branch" >&2
|
|
77
|
+
echo "Feature branches should be named like: 001-feature-name" >&2
|
|
78
|
+
return 1
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
return 0
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
get_feature_dir() { echo "$1/specs/$2"; }
|
|
85
|
+
|
|
86
|
+
get_feature_paths() {
|
|
87
|
+
local repo_root=$(get_repo_root)
|
|
88
|
+
local current_branch=$(get_current_branch)
|
|
89
|
+
local has_git_repo="false"
|
|
90
|
+
|
|
91
|
+
if has_git; then
|
|
92
|
+
has_git_repo="true"
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
local feature_dir=$(get_feature_dir "$repo_root" "$current_branch")
|
|
96
|
+
|
|
97
|
+
cat <<EOF
|
|
98
|
+
REPO_ROOT='$repo_root'
|
|
99
|
+
CURRENT_BRANCH='$current_branch'
|
|
100
|
+
HAS_GIT='$has_git_repo'
|
|
101
|
+
FEATURE_DIR='$feature_dir'
|
|
102
|
+
FEATURE_SPEC='$feature_dir/spec.md'
|
|
103
|
+
IMPL_PLAN='$feature_dir/plan.md'
|
|
104
|
+
TASKS='$feature_dir/tasks.md'
|
|
105
|
+
RESEARCH='$feature_dir/research.md'
|
|
106
|
+
DATA_MODEL='$feature_dir/data-model.md'
|
|
107
|
+
QUICKSTART='$feature_dir/quickstart.md'
|
|
108
|
+
CONTRACTS_DIR='$feature_dir/contracts'
|
|
109
|
+
EOF
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
check_file() { [[ -f "$1" ]] && echo " ✓ $2" || echo " ✗ $2"; }
|
|
113
|
+
check_dir() { [[ -d "$1" && -n $(ls -A "$1" 2>/dev/null) ]] && echo " ✓ $2" || echo " ✗ $2"; }
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
set -e
|
|
4
|
+
|
|
5
|
+
JSON_MODE=false
|
|
6
|
+
ARGS=()
|
|
7
|
+
for arg in "$@"; do
|
|
8
|
+
case "$arg" in
|
|
9
|
+
--json) JSON_MODE=true ;;
|
|
10
|
+
--help|-h) echo "Usage: $0 [--json] <feature_description>"; exit 0 ;;
|
|
11
|
+
*) ARGS+=("$arg") ;;
|
|
12
|
+
esac
|
|
13
|
+
done
|
|
14
|
+
|
|
15
|
+
FEATURE_DESCRIPTION="${ARGS[*]}"
|
|
16
|
+
if [ -z "$FEATURE_DESCRIPTION" ]; then
|
|
17
|
+
echo "Usage: $0 [--json] <feature_description>" >&2
|
|
18
|
+
exit 1
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
# Function to find the repository root by searching for existing project markers
|
|
22
|
+
find_repo_root() {
|
|
23
|
+
local dir="$1"
|
|
24
|
+
while [ "$dir" != "/" ]; do
|
|
25
|
+
if [ -d "$dir/.git" ] || [ -d "$dir/.specify" ]; then
|
|
26
|
+
echo "$dir"
|
|
27
|
+
return 0
|
|
28
|
+
fi
|
|
29
|
+
dir="$(dirname "$dir")"
|
|
30
|
+
done
|
|
31
|
+
return 1
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
# Resolve repository root. Prefer git information when available, but fall back
|
|
35
|
+
# to searching for repository markers so the workflow still functions in repositories that
|
|
36
|
+
# were initialised with --no-git.
|
|
37
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
38
|
+
|
|
39
|
+
if git rev-parse --show-toplevel >/dev/null 2>&1; then
|
|
40
|
+
REPO_ROOT=$(git rev-parse --show-toplevel)
|
|
41
|
+
HAS_GIT=true
|
|
42
|
+
else
|
|
43
|
+
REPO_ROOT="$(find_repo_root "$SCRIPT_DIR")"
|
|
44
|
+
if [ -z "$REPO_ROOT" ]; then
|
|
45
|
+
echo "Error: Could not determine repository root. Please run this script from within the repository." >&2
|
|
46
|
+
exit 1
|
|
47
|
+
fi
|
|
48
|
+
HAS_GIT=false
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
cd "$REPO_ROOT"
|
|
52
|
+
|
|
53
|
+
SPECS_DIR="$REPO_ROOT/specs"
|
|
54
|
+
mkdir -p "$SPECS_DIR"
|
|
55
|
+
|
|
56
|
+
HIGHEST=0
|
|
57
|
+
if [ -d "$SPECS_DIR" ]; then
|
|
58
|
+
for dir in "$SPECS_DIR"/*; do
|
|
59
|
+
[ -d "$dir" ] || continue
|
|
60
|
+
dirname=$(basename "$dir")
|
|
61
|
+
number=$(echo "$dirname" | grep -o '^[0-9]\+' || echo "0")
|
|
62
|
+
number=$((10#$number))
|
|
63
|
+
if [ "$number" -gt "$HIGHEST" ]; then HIGHEST=$number; fi
|
|
64
|
+
done
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
NEXT=$((HIGHEST + 1))
|
|
68
|
+
FEATURE_NUM=$(printf "%03d" "$NEXT")
|
|
69
|
+
|
|
70
|
+
BRANCH_NAME=$(echo "$FEATURE_DESCRIPTION" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/-\+/-/g' | sed 's/^-//' | sed 's/-$//')
|
|
71
|
+
WORDS=$(echo "$BRANCH_NAME" | tr '-' '\n' | grep -v '^$' | head -3 | tr '\n' '-' | sed 's/-$//')
|
|
72
|
+
BRANCH_NAME="${FEATURE_NUM}-${WORDS}"
|
|
73
|
+
|
|
74
|
+
if [ "$HAS_GIT" = true ]; then
|
|
75
|
+
git checkout -b "$BRANCH_NAME"
|
|
76
|
+
else
|
|
77
|
+
>&2 echo "[specify] Warning: Git repository not detected; skipped branch creation for $BRANCH_NAME"
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
FEATURE_DIR="$SPECS_DIR/$BRANCH_NAME"
|
|
81
|
+
mkdir -p "$FEATURE_DIR"
|
|
82
|
+
|
|
83
|
+
TEMPLATE="$REPO_ROOT/.specify/templates/spec-template.md"
|
|
84
|
+
SPEC_FILE="$FEATURE_DIR/spec.md"
|
|
85
|
+
if [ -f "$TEMPLATE" ]; then cp "$TEMPLATE" "$SPEC_FILE"; else touch "$SPEC_FILE"; fi
|
|
86
|
+
|
|
87
|
+
# Set the SPECIFY_FEATURE environment variable for the current session
|
|
88
|
+
export SPECIFY_FEATURE="$BRANCH_NAME"
|
|
89
|
+
|
|
90
|
+
if $JSON_MODE; then
|
|
91
|
+
printf '{"BRANCH_NAME":"%s","SPEC_FILE":"%s","FEATURE_NUM":"%s"}\n' "$BRANCH_NAME" "$SPEC_FILE" "$FEATURE_NUM"
|
|
92
|
+
else
|
|
93
|
+
echo "BRANCH_NAME: $BRANCH_NAME"
|
|
94
|
+
echo "SPEC_FILE: $SPEC_FILE"
|
|
95
|
+
echo "FEATURE_NUM: $FEATURE_NUM"
|
|
96
|
+
echo "SPECIFY_FEATURE environment variable set to: $BRANCH_NAME"
|
|
97
|
+
fi
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
set -e
|
|
4
|
+
|
|
5
|
+
# Parse command line arguments
|
|
6
|
+
JSON_MODE=false
|
|
7
|
+
ARGS=()
|
|
8
|
+
|
|
9
|
+
for arg in "$@"; do
|
|
10
|
+
case "$arg" in
|
|
11
|
+
--json)
|
|
12
|
+
JSON_MODE=true
|
|
13
|
+
;;
|
|
14
|
+
--help|-h)
|
|
15
|
+
echo "Usage: $0 [--json]"
|
|
16
|
+
echo " --json Output results in JSON format"
|
|
17
|
+
echo " --help Show this help message"
|
|
18
|
+
exit 0
|
|
19
|
+
;;
|
|
20
|
+
*)
|
|
21
|
+
ARGS+=("$arg")
|
|
22
|
+
;;
|
|
23
|
+
esac
|
|
24
|
+
done
|
|
25
|
+
|
|
26
|
+
# Get script directory and load common functions
|
|
27
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
28
|
+
source "$SCRIPT_DIR/common.sh"
|
|
29
|
+
|
|
30
|
+
# Get all paths and variables from common functions
|
|
31
|
+
eval $(get_feature_paths)
|
|
32
|
+
|
|
33
|
+
# Check if we're on a proper feature branch (only for git repos)
|
|
34
|
+
check_feature_branch "$CURRENT_BRANCH" "$HAS_GIT" || exit 1
|
|
35
|
+
|
|
36
|
+
# Ensure the feature directory exists
|
|
37
|
+
mkdir -p "$FEATURE_DIR"
|
|
38
|
+
|
|
39
|
+
# Copy plan template if it exists
|
|
40
|
+
TEMPLATE="$REPO_ROOT/.specify/templates/plan-template.md"
|
|
41
|
+
if [[ -f "$TEMPLATE" ]]; then
|
|
42
|
+
cp "$TEMPLATE" "$IMPL_PLAN"
|
|
43
|
+
echo "Copied plan template to $IMPL_PLAN"
|
|
44
|
+
else
|
|
45
|
+
echo "Warning: Plan template not found at $TEMPLATE"
|
|
46
|
+
# Create a basic plan file if template doesn't exist
|
|
47
|
+
touch "$IMPL_PLAN"
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
# Output results
|
|
51
|
+
if $JSON_MODE; then
|
|
52
|
+
printf '{"FEATURE_SPEC":"%s","IMPL_PLAN":"%s","SPECS_DIR":"%s","BRANCH":"%s","HAS_GIT":"%s"}\n' \
|
|
53
|
+
"$FEATURE_SPEC" "$IMPL_PLAN" "$FEATURE_DIR" "$CURRENT_BRANCH" "$HAS_GIT"
|
|
54
|
+
else
|
|
55
|
+
echo "FEATURE_SPEC: $FEATURE_SPEC"
|
|
56
|
+
echo "IMPL_PLAN: $IMPL_PLAN"
|
|
57
|
+
echo "SPECS_DIR: $FEATURE_DIR"
|
|
58
|
+
echo "BRANCH: $CURRENT_BRANCH"
|
|
59
|
+
echo "HAS_GIT: $HAS_GIT"
|
|
60
|
+
fi
|