@rpamis/comet 0.2.5 → 0.2.7
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/LICENSE +21 -21
- package/README.md +16 -5
- package/assets/manifest.json +1 -1
- package/assets/skills/comet/SKILL.md +19 -1
- package/assets/skills/comet/scripts/comet-archive.sh +255 -258
- package/assets/skills/comet/scripts/comet-guard.sh +407 -257
- package/assets/skills/comet/scripts/comet-state.sh +680 -616
- package/assets/skills/comet/scripts/comet-yaml-validate.sh +157 -138
- package/assets/skills/comet-archive/SKILL.md +3 -0
- package/assets/skills/comet-build/SKILL.md +27 -1
- package/assets/skills-zh/comet/SKILL.md +15 -1
- package/assets/skills-zh/comet-archive/SKILL.md +3 -0
- package/assets/skills-zh/comet-build/SKILL.md +27 -1
- package/bin/comet.js +3 -3
- package/dist/core/openspec.d.ts +3 -1
- package/dist/core/openspec.d.ts.map +1 -1
- package/dist/core/openspec.js +13 -5
- package/dist/core/openspec.js.map +1 -1
- package/dist/core/superpowers.d.ts +2 -1
- package/dist/core/superpowers.d.ts.map +1 -1
- package/dist/core/superpowers.js +23 -20
- package/dist/core/superpowers.js.map +1 -1
- package/package.json +1 -1
- package/scripts/postinstall.js +44 -44
|
@@ -1,258 +1,255 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# Comet Archive — automates the archive phase in one command
|
|
3
|
-
# Usage: comet-archive.sh <change-name> [--dry-run]
|
|
4
|
-
# Exit 0 = archive complete, exit 1 = fatal error
|
|
5
|
-
|
|
6
|
-
set -euo pipefail
|
|
7
|
-
|
|
8
|
-
red() { echo -e "\033[31m$1\033[0m" >&2; }
|
|
9
|
-
green() { echo -e "\033[32m$1\033[0m" >&2; }
|
|
10
|
-
yellow() { echo -e "\033[33m$1\033[0m" >&2; }
|
|
11
|
-
|
|
12
|
-
DRY_RUN=0
|
|
13
|
-
if [[ "${2:-}" == "--dry-run" ]]; then
|
|
14
|
-
DRY_RUN=1
|
|
15
|
-
fi
|
|
16
|
-
|
|
17
|
-
# Input validation
|
|
18
|
-
validate_change_name() {
|
|
19
|
-
local name="$1"
|
|
20
|
-
if [ -z "$name" ]; then
|
|
21
|
-
red "FATAL: Change name cannot be empty"
|
|
22
|
-
exit 1
|
|
23
|
-
fi
|
|
24
|
-
if [[ ! "$name" =~ ^[a-zA-Z0-9_-]+$ ]]; then
|
|
25
|
-
red "FATAL: Invalid change name: '$name'"
|
|
26
|
-
red "Valid characters: a-z, A-Z, 0-9, -, _"
|
|
27
|
-
exit 1
|
|
28
|
-
fi
|
|
29
|
-
if [[ "$name" =~ \.\. ]]; then
|
|
30
|
-
red "FATAL: Change name cannot contain '..'"
|
|
31
|
-
exit 1
|
|
32
|
-
fi
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
CHANGE="$1"
|
|
36
|
-
validate_change_name "$CHANGE"
|
|
37
|
-
|
|
38
|
-
CHANGE_DIR="openspec/changes/$CHANGE"
|
|
39
|
-
YAML="$CHANGE_DIR/.comet.yaml"
|
|
40
|
-
SCRIPT_DIR="$(cd "$(dirname "$(readlink -f "$0" 2>/dev/null || echo "$0")" 2>/dev/null || dirname "$0")" && pwd)"
|
|
41
|
-
STATE_SH="$SCRIPT_DIR/comet-state.sh"
|
|
42
|
-
TODAY=$(date +%Y-%m-%d)
|
|
43
|
-
ARCHIVE_NAME="${TODAY}-${CHANGE}"
|
|
44
|
-
ARCHIVE_DIR="openspec/changes/archive/${ARCHIVE_NAME}"
|
|
45
|
-
|
|
46
|
-
STEPS_OK=0
|
|
47
|
-
STEPS_TOTAL=0
|
|
48
|
-
|
|
49
|
-
step_ok() {
|
|
50
|
-
green " [OK] $1"
|
|
51
|
-
STEPS_OK=$((STEPS_OK + 1))
|
|
52
|
-
STEPS_TOTAL=$((STEPS_TOTAL + 1))
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
step_fail() {
|
|
56
|
-
red " [FAIL] $1"
|
|
57
|
-
STEPS_TOTAL=$((STEPS_TOTAL + 1))
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
if [
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
fi
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
if [ "$
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
if [ "$
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
tmp_file
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
else
|
|
222
|
-
mkdir -p "openspec/changes/archive"
|
|
223
|
-
mv "$CHANGE_DIR" "$ARCHIVE_DIR"
|
|
224
|
-
step_ok "Moved to: $ARCHIVE_DIR"
|
|
225
|
-
fi
|
|
226
|
-
|
|
227
|
-
# --- Step 8: Mark archived via comet-state transition ---
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
fi
|
|
257
|
-
|
|
258
|
-
exit 0
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Comet Archive — automates the archive phase in one command
|
|
3
|
+
# Usage: comet-archive.sh <change-name> [--dry-run]
|
|
4
|
+
# Exit 0 = archive complete, exit 1 = fatal error
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
red() { echo -e "\033[31m$1\033[0m" >&2; }
|
|
9
|
+
green() { echo -e "\033[32m$1\033[0m" >&2; }
|
|
10
|
+
yellow() { echo -e "\033[33m$1\033[0m" >&2; }
|
|
11
|
+
|
|
12
|
+
DRY_RUN=0
|
|
13
|
+
if [[ "${2:-}" == "--dry-run" ]]; then
|
|
14
|
+
DRY_RUN=1
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
# Input validation
|
|
18
|
+
validate_change_name() {
|
|
19
|
+
local name="$1"
|
|
20
|
+
if [ -z "$name" ]; then
|
|
21
|
+
red "FATAL: Change name cannot be empty"
|
|
22
|
+
exit 1
|
|
23
|
+
fi
|
|
24
|
+
if [[ ! "$name" =~ ^[a-zA-Z0-9_-]+$ ]]; then
|
|
25
|
+
red "FATAL: Invalid change name: '$name'"
|
|
26
|
+
red "Valid characters: a-z, A-Z, 0-9, -, _"
|
|
27
|
+
exit 1
|
|
28
|
+
fi
|
|
29
|
+
if [[ "$name" =~ \.\. ]]; then
|
|
30
|
+
red "FATAL: Change name cannot contain '..'"
|
|
31
|
+
exit 1
|
|
32
|
+
fi
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
CHANGE="$1"
|
|
36
|
+
validate_change_name "$CHANGE"
|
|
37
|
+
|
|
38
|
+
CHANGE_DIR="openspec/changes/$CHANGE"
|
|
39
|
+
YAML="$CHANGE_DIR/.comet.yaml"
|
|
40
|
+
SCRIPT_DIR="$(cd "$(dirname "$(readlink -f "$0" 2>/dev/null || echo "$0")" 2>/dev/null || dirname "$0")" && pwd)"
|
|
41
|
+
STATE_SH="$SCRIPT_DIR/comet-state.sh"
|
|
42
|
+
TODAY=$(date +%Y-%m-%d)
|
|
43
|
+
ARCHIVE_NAME="${TODAY}-${CHANGE}"
|
|
44
|
+
ARCHIVE_DIR="openspec/changes/archive/${ARCHIVE_NAME}"
|
|
45
|
+
|
|
46
|
+
STEPS_OK=0
|
|
47
|
+
STEPS_TOTAL=0
|
|
48
|
+
|
|
49
|
+
step_ok() {
|
|
50
|
+
green " [OK] $1"
|
|
51
|
+
STEPS_OK=$((STEPS_OK + 1))
|
|
52
|
+
STEPS_TOTAL=$((STEPS_TOTAL + 1))
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
step_fail() {
|
|
56
|
+
red " [FAIL] $1"
|
|
57
|
+
STEPS_TOTAL=$((STEPS_TOTAL + 1))
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
step_dry_run() {
|
|
61
|
+
yellow " [DRY-RUN] $1"
|
|
62
|
+
STEPS_OK=$((STEPS_OK + 1))
|
|
63
|
+
STEPS_TOTAL=$((STEPS_TOTAL + 1))
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
echo "=== Comet Archive: $CHANGE ===" >&2
|
|
67
|
+
|
|
68
|
+
# --- Step 1: Read .comet.yaml, extract paths ---
|
|
69
|
+
|
|
70
|
+
yaml_field() {
|
|
71
|
+
local field="$1"
|
|
72
|
+
if [ -f "$STATE_SH" ]; then
|
|
73
|
+
bash "$STATE_SH" get "$CHANGE" "$field" 2>/dev/null
|
|
74
|
+
else
|
|
75
|
+
if [ -f "$YAML" ]; then
|
|
76
|
+
grep "^${field}:" "$YAML" | sed "s/^${field}: *//" | tr -d '"' | tr -d "'"
|
|
77
|
+
fi
|
|
78
|
+
fi
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if [ ! -f "$YAML" ]; then
|
|
82
|
+
red "FATAL: .comet.yaml not found in $CHANGE_DIR/"
|
|
83
|
+
exit 1
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
DESIGN_DOC=$(yaml_field "design_doc")
|
|
87
|
+
PLAN_PATH=$(yaml_field "plan")
|
|
88
|
+
|
|
89
|
+
# --- Step 2: Validate entry state ---
|
|
90
|
+
|
|
91
|
+
PHASE_VAL=$(yaml_field "phase")
|
|
92
|
+
VERIFY_VAL=$(yaml_field "verify_result")
|
|
93
|
+
ARCHIVED_VAL=$(yaml_field "archived")
|
|
94
|
+
|
|
95
|
+
if [ "$PHASE_VAL" != "archive" ]; then
|
|
96
|
+
red "FATAL: phase is '$PHASE_VAL', expected 'archive'"
|
|
97
|
+
exit 1
|
|
98
|
+
fi
|
|
99
|
+
|
|
100
|
+
if [ "$VERIFY_VAL" != "pass" ]; then
|
|
101
|
+
red "FATAL: verify_result is '$VERIFY_VAL', expected 'pass'. Run comet-verify first."
|
|
102
|
+
exit 1
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
if [ "$ARCHIVED_VAL" = "true" ]; then
|
|
106
|
+
red "FATAL: change already archived"
|
|
107
|
+
exit 1
|
|
108
|
+
fi
|
|
109
|
+
|
|
110
|
+
step_ok "Entry state verified"
|
|
111
|
+
|
|
112
|
+
# --- Step 3: Check archive target ---
|
|
113
|
+
|
|
114
|
+
if [ -d "$ARCHIVE_DIR" ]; then
|
|
115
|
+
red "FATAL: archive target already exists: $ARCHIVE_DIR"
|
|
116
|
+
exit 1
|
|
117
|
+
fi
|
|
118
|
+
|
|
119
|
+
step_ok "Archive target available"
|
|
120
|
+
|
|
121
|
+
# --- Step 4: Sync delta specs → main specs ---
|
|
122
|
+
|
|
123
|
+
sync_delta_specs() {
|
|
124
|
+
local delta_root="$CHANGE_DIR/specs"
|
|
125
|
+
if [ ! -d "$delta_root" ]; then
|
|
126
|
+
return 0
|
|
127
|
+
fi
|
|
128
|
+
|
|
129
|
+
for delta_spec_dir in "$delta_root"/*/; do
|
|
130
|
+
[ -d "$delta_spec_dir" ] || continue
|
|
131
|
+
local capability
|
|
132
|
+
capability=$(basename "$delta_spec_dir")
|
|
133
|
+
local delta_spec="$delta_spec_dir/spec.md"
|
|
134
|
+
local main_spec="openspec/specs/$capability/spec.md"
|
|
135
|
+
|
|
136
|
+
if [ ! -f "$delta_spec" ]; then
|
|
137
|
+
continue
|
|
138
|
+
fi
|
|
139
|
+
|
|
140
|
+
if [ "$DRY_RUN" -eq 1 ]; then
|
|
141
|
+
step_dry_run "Would sync: $capability → $main_spec"
|
|
142
|
+
continue
|
|
143
|
+
fi
|
|
144
|
+
|
|
145
|
+
if [ ! -f "$main_spec" ]; then
|
|
146
|
+
mkdir -p "openspec/specs/$capability"
|
|
147
|
+
elif ! cmp -s "$main_spec" "$delta_spec"; then
|
|
148
|
+
yellow " [DIFF] Delta spec differs from main spec before sync: $capability"
|
|
149
|
+
diff -u "$main_spec" "$delta_spec" >&2 || true
|
|
150
|
+
fi
|
|
151
|
+
cp "$delta_spec" "$main_spec"
|
|
152
|
+
|
|
153
|
+
step_ok "Delta spec synced: $capability → openspec/specs/$capability/spec.md"
|
|
154
|
+
done
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
sync_delta_specs
|
|
158
|
+
|
|
159
|
+
# --- Step 5: Annotate design doc frontmatter ---
|
|
160
|
+
|
|
161
|
+
annotate_frontmatter() {
|
|
162
|
+
local file="$1"
|
|
163
|
+
local extra_fields="$2"
|
|
164
|
+
|
|
165
|
+
if [ ! -f "$file" ]; then
|
|
166
|
+
return 0
|
|
167
|
+
fi
|
|
168
|
+
|
|
169
|
+
if [ "$DRY_RUN" -eq 1 ]; then
|
|
170
|
+
step_dry_run "Would annotate: $file"
|
|
171
|
+
return 0
|
|
172
|
+
fi
|
|
173
|
+
|
|
174
|
+
if head -1 "$file" | grep -q '^---'; then
|
|
175
|
+
local tmp_file
|
|
176
|
+
tmp_file=$(mktemp)
|
|
177
|
+
awk -v archive="$ARCHIVE_NAME" -v extra="$extra_fields" '
|
|
178
|
+
/^archived-with:/ { next }
|
|
179
|
+
NR==1 && /^---/ { print; next }
|
|
180
|
+
/^---/ && NR>1 {
|
|
181
|
+
print "archived-with: " archive
|
|
182
|
+
if (extra != "") print extra
|
|
183
|
+
print; next
|
|
184
|
+
}
|
|
185
|
+
{ print }
|
|
186
|
+
' "$file" > "$tmp_file"
|
|
187
|
+
mv "$tmp_file" "$file"
|
|
188
|
+
else
|
|
189
|
+
local tmp_file
|
|
190
|
+
tmp_file=$(mktemp)
|
|
191
|
+
{
|
|
192
|
+
echo "---"
|
|
193
|
+
echo "archived-with: $ARCHIVE_NAME"
|
|
194
|
+
if [ -n "$extra_fields" ]; then
|
|
195
|
+
echo "$extra_fields"
|
|
196
|
+
fi
|
|
197
|
+
echo "status: final"
|
|
198
|
+
echo "---"
|
|
199
|
+
cat "$file"
|
|
200
|
+
} > "$tmp_file"
|
|
201
|
+
mv "$tmp_file" "$file"
|
|
202
|
+
fi
|
|
203
|
+
|
|
204
|
+
step_ok "Annotated: $file"
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if [ -n "$DESIGN_DOC" ] && [ "$DESIGN_DOC" != "null" ]; then
|
|
208
|
+
annotate_frontmatter "$DESIGN_DOC" "status: final"
|
|
209
|
+
fi
|
|
210
|
+
|
|
211
|
+
# --- Step 6: Annotate plan frontmatter ---
|
|
212
|
+
|
|
213
|
+
if [ -n "$PLAN_PATH" ] && [ "$PLAN_PATH" != "null" ]; then
|
|
214
|
+
annotate_frontmatter "$PLAN_PATH" ""
|
|
215
|
+
fi
|
|
216
|
+
|
|
217
|
+
# --- Step 7: Move change to archive ---
|
|
218
|
+
|
|
219
|
+
if [ "$DRY_RUN" -eq 1 ]; then
|
|
220
|
+
step_dry_run "Would move: $CHANGE_DIR → $ARCHIVE_DIR"
|
|
221
|
+
else
|
|
222
|
+
mkdir -p "openspec/changes/archive"
|
|
223
|
+
mv "$CHANGE_DIR" "$ARCHIVE_DIR"
|
|
224
|
+
step_ok "Moved to: $ARCHIVE_DIR"
|
|
225
|
+
fi
|
|
226
|
+
|
|
227
|
+
# --- Step 8: Mark archived via comet-state transition ---
|
|
228
|
+
|
|
229
|
+
ARCHIVE_YAML="$ARCHIVE_DIR/.comet.yaml"
|
|
230
|
+
|
|
231
|
+
if [ "$DRY_RUN" -eq 1 ]; then
|
|
232
|
+
step_dry_run "Would set archived: true in $ARCHIVE_YAML"
|
|
233
|
+
else
|
|
234
|
+
if [ -f "$ARCHIVE_YAML" ]; then
|
|
235
|
+
bash "$STATE_SH" transition "$ARCHIVE_NAME" archived >/dev/null
|
|
236
|
+
step_ok "archived: true"
|
|
237
|
+
else
|
|
238
|
+
step_fail "archived: true (.comet.yaml not found after move)"
|
|
239
|
+
fi
|
|
240
|
+
fi
|
|
241
|
+
|
|
242
|
+
# --- Step 9: Print summary ---
|
|
243
|
+
|
|
244
|
+
echo "" >&2
|
|
245
|
+
if [ "$DRY_RUN" -eq 1 ]; then
|
|
246
|
+
yellow "Dry run complete. $STEPS_OK/$STEPS_TOTAL steps would succeed."
|
|
247
|
+
else
|
|
248
|
+
green "Archive complete. $STEPS_OK/$STEPS_TOTAL steps succeeded."
|
|
249
|
+
fi
|
|
250
|
+
|
|
251
|
+
if [ "$STEPS_OK" -lt "$STEPS_TOTAL" ]; then
|
|
252
|
+
exit 1
|
|
253
|
+
fi
|
|
254
|
+
|
|
255
|
+
exit 0
|