@rpamis/comet 0.2.0 → 0.2.2
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 +270 -270
- package/assets/manifest.json +21 -21
- package/assets/skills/comet/scripts/comet-archive.sh +258 -258
- package/assets/skills/comet/scripts/comet-guard.sh +7 -5
- package/assets/skills/comet/scripts/comet-state.sh +497 -496
- package/assets/skills/comet/scripts/comet-yaml-validate.sh +132 -132
- package/assets/skills/comet-archive/SKILL.md +63 -63
- package/assets/skills/comet-build/SKILL.md +153 -153
- package/assets/skills/comet-design/SKILL.md +91 -91
- package/assets/skills/comet-open/SKILL.md +70 -70
- package/assets/skills/comet-verify/SKILL.md +114 -114
- package/assets/skills-zh/comet-archive/SKILL.md +63 -63
- package/assets/skills-zh/comet-build/SKILL.md +153 -153
- package/assets/skills-zh/comet-design/SKILL.md +91 -91
- package/assets/skills-zh/comet-open/SKILL.md +70 -70
- package/assets/skills-zh/comet-verify/SKILL.md +114 -114
- package/bin/comet.js +3 -3
- package/dist/cli/index.js +10 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/core/detect.d.ts +6 -1
- package/dist/core/detect.d.ts.map +1 -1
- package/dist/core/detect.js +29 -1
- package/dist/core/detect.js.map +1 -1
- package/package.json +62 -61
- package/scripts/postinstall.js +44 -44
|
@@ -1,258 +1,258 @@
|
|
|
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
|
-
echo "=== Comet Archive: $CHANGE ===" >&2
|
|
61
|
-
|
|
62
|
-
# --- Step 1: Read .comet.yaml, extract paths ---
|
|
63
|
-
|
|
64
|
-
yaml_field() {
|
|
65
|
-
local field="$1"
|
|
66
|
-
if [ -f "$STATE_SH" ]; then
|
|
67
|
-
bash "$STATE_SH" get "$CHANGE" "$field" 2>/dev/null
|
|
68
|
-
else
|
|
69
|
-
if [ -f "$YAML" ]; then
|
|
70
|
-
grep "^${field}:" "$YAML" | sed "s/^${field}: *//" | tr -d '"' | tr -d "'"
|
|
71
|
-
fi
|
|
72
|
-
fi
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if [ ! -f "$YAML" ]; then
|
|
76
|
-
red "FATAL: .comet.yaml not found in $CHANGE_DIR/"
|
|
77
|
-
exit 1
|
|
78
|
-
fi
|
|
79
|
-
|
|
80
|
-
DESIGN_DOC=$(yaml_field "design_doc")
|
|
81
|
-
PLAN_PATH=$(yaml_field "plan")
|
|
82
|
-
|
|
83
|
-
# --- Step 2: Validate entry state ---
|
|
84
|
-
|
|
85
|
-
PHASE_VAL=$(yaml_field "phase")
|
|
86
|
-
VERIFY_VAL=$(yaml_field "verify_result")
|
|
87
|
-
ARCHIVED_VAL=$(yaml_field "archived")
|
|
88
|
-
|
|
89
|
-
if [ "$PHASE_VAL" != "archive" ]; then
|
|
90
|
-
red "FATAL: phase is '$PHASE_VAL', expected 'archive'"
|
|
91
|
-
exit 1
|
|
92
|
-
fi
|
|
93
|
-
|
|
94
|
-
if [ "$VERIFY_VAL" != "pass" ]; then
|
|
95
|
-
red "FATAL: verify_result is '$VERIFY_VAL', expected 'pass'. Run comet-verify first."
|
|
96
|
-
exit 1
|
|
97
|
-
fi
|
|
98
|
-
|
|
99
|
-
if [ "$ARCHIVED_VAL" = "true" ]; then
|
|
100
|
-
red "FATAL: change already archived"
|
|
101
|
-
exit 1
|
|
102
|
-
fi
|
|
103
|
-
|
|
104
|
-
step_ok "Entry state verified"
|
|
105
|
-
|
|
106
|
-
# --- Step 3: Check archive target ---
|
|
107
|
-
|
|
108
|
-
if [ -d "$ARCHIVE_DIR" ]; then
|
|
109
|
-
red "FATAL: archive target already exists: $ARCHIVE_DIR"
|
|
110
|
-
exit 1
|
|
111
|
-
fi
|
|
112
|
-
|
|
113
|
-
step_ok "Archive target available"
|
|
114
|
-
|
|
115
|
-
# --- Step 4: Sync delta specs → main specs ---
|
|
116
|
-
|
|
117
|
-
sync_delta_specs() {
|
|
118
|
-
local delta_root="$CHANGE_DIR/specs"
|
|
119
|
-
if [ ! -d "$delta_root" ]; then
|
|
120
|
-
return 0
|
|
121
|
-
fi
|
|
122
|
-
|
|
123
|
-
for delta_spec_dir in "$delta_root"/*/; do
|
|
124
|
-
[ -d "$delta_spec_dir" ] || continue
|
|
125
|
-
local capability
|
|
126
|
-
capability=$(basename "$delta_spec_dir")
|
|
127
|
-
local delta_spec="$delta_spec_dir/spec.md"
|
|
128
|
-
local main_spec="openspec/specs/$capability/spec.md"
|
|
129
|
-
|
|
130
|
-
if [ ! -f "$delta_spec" ]; then
|
|
131
|
-
continue
|
|
132
|
-
fi
|
|
133
|
-
|
|
134
|
-
STEPS_TOTAL=$((STEPS_TOTAL + 1))
|
|
135
|
-
|
|
136
|
-
if [ "$DRY_RUN" -eq 1 ]; then
|
|
137
|
-
yellow " [DRY-RUN] Would sync: $capability → $main_spec"
|
|
138
|
-
STEPS_OK=$((STEPS_OK + 1))
|
|
139
|
-
continue
|
|
140
|
-
fi
|
|
141
|
-
|
|
142
|
-
if [ ! -f "$main_spec" ]; then
|
|
143
|
-
mkdir -p "openspec/specs/$capability"
|
|
144
|
-
fi
|
|
145
|
-
cp "$delta_spec" "$main_spec"
|
|
146
|
-
|
|
147
|
-
step_ok "Delta spec synced: $capability → openspec/specs/$capability/spec.md"
|
|
148
|
-
done
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
sync_delta_specs
|
|
152
|
-
|
|
153
|
-
# --- Step 5: Annotate design doc frontmatter ---
|
|
154
|
-
|
|
155
|
-
annotate_frontmatter() {
|
|
156
|
-
local file="$1"
|
|
157
|
-
local extra_fields="$2"
|
|
158
|
-
|
|
159
|
-
if [ ! -f "$file" ]; then
|
|
160
|
-
return 0
|
|
161
|
-
fi
|
|
162
|
-
|
|
163
|
-
STEPS_TOTAL=$((STEPS_TOTAL + 1))
|
|
164
|
-
|
|
165
|
-
if [ "$DRY_RUN" -eq 1 ]; then
|
|
166
|
-
yellow " [DRY-RUN] Would annotate: $file"
|
|
167
|
-
STEPS_OK=$((STEPS_OK + 1))
|
|
168
|
-
return 0
|
|
169
|
-
fi
|
|
170
|
-
|
|
171
|
-
if head -1 "$file" | grep -q '^---'; then
|
|
172
|
-
local tmp_file
|
|
173
|
-
tmp_file=$(mktemp)
|
|
174
|
-
awk -v archive="$ARCHIVE_NAME" -v extra="$extra_fields" '
|
|
175
|
-
/^archived-with:/ { next }
|
|
176
|
-
NR==1 && /^---/ { print; next }
|
|
177
|
-
/^---/ && NR>1 {
|
|
178
|
-
print "archived-with: " archive
|
|
179
|
-
if (extra != "") print extra
|
|
180
|
-
print; next
|
|
181
|
-
}
|
|
182
|
-
{ print }
|
|
183
|
-
' "$file" > "$tmp_file"
|
|
184
|
-
mv "$tmp_file" "$file"
|
|
185
|
-
else
|
|
186
|
-
local tmp_file
|
|
187
|
-
tmp_file=$(mktemp)
|
|
188
|
-
{
|
|
189
|
-
echo "---"
|
|
190
|
-
echo "archived-with: $ARCHIVE_NAME"
|
|
191
|
-
if [ -n "$extra_fields" ]; then
|
|
192
|
-
echo "$extra_fields"
|
|
193
|
-
fi
|
|
194
|
-
echo "status: final"
|
|
195
|
-
echo "---"
|
|
196
|
-
cat "$file"
|
|
197
|
-
} > "$tmp_file"
|
|
198
|
-
mv "$tmp_file" "$file"
|
|
199
|
-
fi
|
|
200
|
-
|
|
201
|
-
step_ok "Annotated: $file"
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
if [ -n "$DESIGN_DOC" ] && [ "$DESIGN_DOC" != "null" ]; then
|
|
205
|
-
annotate_frontmatter "$DESIGN_DOC" "status: final"
|
|
206
|
-
fi
|
|
207
|
-
|
|
208
|
-
# --- Step 6: Annotate plan frontmatter ---
|
|
209
|
-
|
|
210
|
-
if [ -n "$PLAN_PATH" ] && [ "$PLAN_PATH" != "null" ]; then
|
|
211
|
-
annotate_frontmatter "$PLAN_PATH" ""
|
|
212
|
-
fi
|
|
213
|
-
|
|
214
|
-
# --- Step 7: Move change to archive ---
|
|
215
|
-
|
|
216
|
-
STEPS_TOTAL=$((STEPS_TOTAL + 1))
|
|
217
|
-
|
|
218
|
-
if [ "$DRY_RUN" -eq 1 ]; then
|
|
219
|
-
yellow " [DRY-RUN] Would move: $CHANGE_DIR → $ARCHIVE_DIR"
|
|
220
|
-
STEPS_OK=$((STEPS_OK + 1))
|
|
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: Update archived: true in .comet.yaml ---
|
|
228
|
-
|
|
229
|
-
STEPS_TOTAL=$((STEPS_TOTAL + 1))
|
|
230
|
-
|
|
231
|
-
ARCHIVE_YAML="$ARCHIVE_DIR/.comet.yaml"
|
|
232
|
-
|
|
233
|
-
if [ "$DRY_RUN" -eq 1 ]; then
|
|
234
|
-
yellow " [DRY-RUN] Would set archived: true in $ARCHIVE_YAML"
|
|
235
|
-
STEPS_OK=$((STEPS_OK + 1))
|
|
236
|
-
else
|
|
237
|
-
if [ -f "$ARCHIVE_YAML" ]; then
|
|
238
|
-
sed -i 's/^archived:.*/archived: true/' "$ARCHIVE_YAML"
|
|
239
|
-
step_ok "archived: true"
|
|
240
|
-
else
|
|
241
|
-
step_fail "archived: true (.comet.yaml not found after move)"
|
|
242
|
-
fi
|
|
243
|
-
fi
|
|
244
|
-
|
|
245
|
-
# --- Step 9: Print summary ---
|
|
246
|
-
|
|
247
|
-
echo "" >&2
|
|
248
|
-
if [ "$DRY_RUN" -eq 1 ]; then
|
|
249
|
-
yellow "Dry run complete. $STEPS_OK/$STEPS_TOTAL steps would succeed."
|
|
250
|
-
else
|
|
251
|
-
green "Archive complete. $STEPS_OK/$STEPS_TOTAL steps succeeded."
|
|
252
|
-
fi
|
|
253
|
-
|
|
254
|
-
if [ "$STEPS_OK" -lt "$STEPS_TOTAL" ]; then
|
|
255
|
-
exit 1
|
|
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
|
+
echo "=== Comet Archive: $CHANGE ===" >&2
|
|
61
|
+
|
|
62
|
+
# --- Step 1: Read .comet.yaml, extract paths ---
|
|
63
|
+
|
|
64
|
+
yaml_field() {
|
|
65
|
+
local field="$1"
|
|
66
|
+
if [ -f "$STATE_SH" ]; then
|
|
67
|
+
bash "$STATE_SH" get "$CHANGE" "$field" 2>/dev/null
|
|
68
|
+
else
|
|
69
|
+
if [ -f "$YAML" ]; then
|
|
70
|
+
grep "^${field}:" "$YAML" | sed "s/^${field}: *//" | tr -d '"' | tr -d "'"
|
|
71
|
+
fi
|
|
72
|
+
fi
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if [ ! -f "$YAML" ]; then
|
|
76
|
+
red "FATAL: .comet.yaml not found in $CHANGE_DIR/"
|
|
77
|
+
exit 1
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
DESIGN_DOC=$(yaml_field "design_doc")
|
|
81
|
+
PLAN_PATH=$(yaml_field "plan")
|
|
82
|
+
|
|
83
|
+
# --- Step 2: Validate entry state ---
|
|
84
|
+
|
|
85
|
+
PHASE_VAL=$(yaml_field "phase")
|
|
86
|
+
VERIFY_VAL=$(yaml_field "verify_result")
|
|
87
|
+
ARCHIVED_VAL=$(yaml_field "archived")
|
|
88
|
+
|
|
89
|
+
if [ "$PHASE_VAL" != "archive" ]; then
|
|
90
|
+
red "FATAL: phase is '$PHASE_VAL', expected 'archive'"
|
|
91
|
+
exit 1
|
|
92
|
+
fi
|
|
93
|
+
|
|
94
|
+
if [ "$VERIFY_VAL" != "pass" ]; then
|
|
95
|
+
red "FATAL: verify_result is '$VERIFY_VAL', expected 'pass'. Run comet-verify first."
|
|
96
|
+
exit 1
|
|
97
|
+
fi
|
|
98
|
+
|
|
99
|
+
if [ "$ARCHIVED_VAL" = "true" ]; then
|
|
100
|
+
red "FATAL: change already archived"
|
|
101
|
+
exit 1
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
step_ok "Entry state verified"
|
|
105
|
+
|
|
106
|
+
# --- Step 3: Check archive target ---
|
|
107
|
+
|
|
108
|
+
if [ -d "$ARCHIVE_DIR" ]; then
|
|
109
|
+
red "FATAL: archive target already exists: $ARCHIVE_DIR"
|
|
110
|
+
exit 1
|
|
111
|
+
fi
|
|
112
|
+
|
|
113
|
+
step_ok "Archive target available"
|
|
114
|
+
|
|
115
|
+
# --- Step 4: Sync delta specs → main specs ---
|
|
116
|
+
|
|
117
|
+
sync_delta_specs() {
|
|
118
|
+
local delta_root="$CHANGE_DIR/specs"
|
|
119
|
+
if [ ! -d "$delta_root" ]; then
|
|
120
|
+
return 0
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
for delta_spec_dir in "$delta_root"/*/; do
|
|
124
|
+
[ -d "$delta_spec_dir" ] || continue
|
|
125
|
+
local capability
|
|
126
|
+
capability=$(basename "$delta_spec_dir")
|
|
127
|
+
local delta_spec="$delta_spec_dir/spec.md"
|
|
128
|
+
local main_spec="openspec/specs/$capability/spec.md"
|
|
129
|
+
|
|
130
|
+
if [ ! -f "$delta_spec" ]; then
|
|
131
|
+
continue
|
|
132
|
+
fi
|
|
133
|
+
|
|
134
|
+
STEPS_TOTAL=$((STEPS_TOTAL + 1))
|
|
135
|
+
|
|
136
|
+
if [ "$DRY_RUN" -eq 1 ]; then
|
|
137
|
+
yellow " [DRY-RUN] Would sync: $capability → $main_spec"
|
|
138
|
+
STEPS_OK=$((STEPS_OK + 1))
|
|
139
|
+
continue
|
|
140
|
+
fi
|
|
141
|
+
|
|
142
|
+
if [ ! -f "$main_spec" ]; then
|
|
143
|
+
mkdir -p "openspec/specs/$capability"
|
|
144
|
+
fi
|
|
145
|
+
cp "$delta_spec" "$main_spec"
|
|
146
|
+
|
|
147
|
+
step_ok "Delta spec synced: $capability → openspec/specs/$capability/spec.md"
|
|
148
|
+
done
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
sync_delta_specs
|
|
152
|
+
|
|
153
|
+
# --- Step 5: Annotate design doc frontmatter ---
|
|
154
|
+
|
|
155
|
+
annotate_frontmatter() {
|
|
156
|
+
local file="$1"
|
|
157
|
+
local extra_fields="$2"
|
|
158
|
+
|
|
159
|
+
if [ ! -f "$file" ]; then
|
|
160
|
+
return 0
|
|
161
|
+
fi
|
|
162
|
+
|
|
163
|
+
STEPS_TOTAL=$((STEPS_TOTAL + 1))
|
|
164
|
+
|
|
165
|
+
if [ "$DRY_RUN" -eq 1 ]; then
|
|
166
|
+
yellow " [DRY-RUN] Would annotate: $file"
|
|
167
|
+
STEPS_OK=$((STEPS_OK + 1))
|
|
168
|
+
return 0
|
|
169
|
+
fi
|
|
170
|
+
|
|
171
|
+
if head -1 "$file" | grep -q '^---'; then
|
|
172
|
+
local tmp_file
|
|
173
|
+
tmp_file=$(mktemp)
|
|
174
|
+
awk -v archive="$ARCHIVE_NAME" -v extra="$extra_fields" '
|
|
175
|
+
/^archived-with:/ { next }
|
|
176
|
+
NR==1 && /^---/ { print; next }
|
|
177
|
+
/^---/ && NR>1 {
|
|
178
|
+
print "archived-with: " archive
|
|
179
|
+
if (extra != "") print extra
|
|
180
|
+
print; next
|
|
181
|
+
}
|
|
182
|
+
{ print }
|
|
183
|
+
' "$file" > "$tmp_file"
|
|
184
|
+
mv "$tmp_file" "$file"
|
|
185
|
+
else
|
|
186
|
+
local tmp_file
|
|
187
|
+
tmp_file=$(mktemp)
|
|
188
|
+
{
|
|
189
|
+
echo "---"
|
|
190
|
+
echo "archived-with: $ARCHIVE_NAME"
|
|
191
|
+
if [ -n "$extra_fields" ]; then
|
|
192
|
+
echo "$extra_fields"
|
|
193
|
+
fi
|
|
194
|
+
echo "status: final"
|
|
195
|
+
echo "---"
|
|
196
|
+
cat "$file"
|
|
197
|
+
} > "$tmp_file"
|
|
198
|
+
mv "$tmp_file" "$file"
|
|
199
|
+
fi
|
|
200
|
+
|
|
201
|
+
step_ok "Annotated: $file"
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if [ -n "$DESIGN_DOC" ] && [ "$DESIGN_DOC" != "null" ]; then
|
|
205
|
+
annotate_frontmatter "$DESIGN_DOC" "status: final"
|
|
206
|
+
fi
|
|
207
|
+
|
|
208
|
+
# --- Step 6: Annotate plan frontmatter ---
|
|
209
|
+
|
|
210
|
+
if [ -n "$PLAN_PATH" ] && [ "$PLAN_PATH" != "null" ]; then
|
|
211
|
+
annotate_frontmatter "$PLAN_PATH" ""
|
|
212
|
+
fi
|
|
213
|
+
|
|
214
|
+
# --- Step 7: Move change to archive ---
|
|
215
|
+
|
|
216
|
+
STEPS_TOTAL=$((STEPS_TOTAL + 1))
|
|
217
|
+
|
|
218
|
+
if [ "$DRY_RUN" -eq 1 ]; then
|
|
219
|
+
yellow " [DRY-RUN] Would move: $CHANGE_DIR → $ARCHIVE_DIR"
|
|
220
|
+
STEPS_OK=$((STEPS_OK + 1))
|
|
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: Update archived: true in .comet.yaml ---
|
|
228
|
+
|
|
229
|
+
STEPS_TOTAL=$((STEPS_TOTAL + 1))
|
|
230
|
+
|
|
231
|
+
ARCHIVE_YAML="$ARCHIVE_DIR/.comet.yaml"
|
|
232
|
+
|
|
233
|
+
if [ "$DRY_RUN" -eq 1 ]; then
|
|
234
|
+
yellow " [DRY-RUN] Would set archived: true in $ARCHIVE_YAML"
|
|
235
|
+
STEPS_OK=$((STEPS_OK + 1))
|
|
236
|
+
else
|
|
237
|
+
if [ -f "$ARCHIVE_YAML" ]; then
|
|
238
|
+
sed -i 's/^archived:.*/archived: true/' "$ARCHIVE_YAML"
|
|
239
|
+
step_ok "archived: true"
|
|
240
|
+
else
|
|
241
|
+
step_fail "archived: true (.comet.yaml not found after move)"
|
|
242
|
+
fi
|
|
243
|
+
fi
|
|
244
|
+
|
|
245
|
+
# --- Step 9: Print summary ---
|
|
246
|
+
|
|
247
|
+
echo "" >&2
|
|
248
|
+
if [ "$DRY_RUN" -eq 1 ]; then
|
|
249
|
+
yellow "Dry run complete. $STEPS_OK/$STEPS_TOTAL steps would succeed."
|
|
250
|
+
else
|
|
251
|
+
green "Archive complete. $STEPS_OK/$STEPS_TOTAL steps succeeded."
|
|
252
|
+
fi
|
|
253
|
+
|
|
254
|
+
if [ "$STEPS_OK" -lt "$STEPS_TOTAL" ]; then
|
|
255
|
+
exit 1
|
|
256
|
+
fi
|
|
257
|
+
|
|
258
|
+
exit 0
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
# Usage: comet-guard.sh <change-name> <current-phase> [--apply]
|
|
4
4
|
# Phases: open, design, build, verify, archive
|
|
5
5
|
# Exit 0 = all checks pass, exit 1 = blocked (reasons printed to stderr)
|
|
6
|
+
# shellcheck disable=SC2329 # Functions called indirectly via check() dispatch
|
|
6
7
|
|
|
7
8
|
set -euo pipefail
|
|
8
9
|
|
|
@@ -111,11 +112,12 @@ preflight() {
|
|
|
111
112
|
fi
|
|
112
113
|
}
|
|
113
114
|
|
|
114
|
-
|
|
115
|
+
build_passes() {
|
|
115
116
|
if [ "${COMET_SKIP_BUILD:-0}" = "1" ]; then
|
|
116
117
|
return 0
|
|
117
118
|
fi
|
|
118
|
-
|
|
119
|
+
# Attempt common build commands; succeeds if any pass
|
|
120
|
+
(npm run build 2>/dev/null) || (mvn compile -q 2>/dev/null) || (cargo build 2>/dev/null) || true
|
|
119
121
|
}
|
|
120
122
|
|
|
121
123
|
verify_result_is_pass() {
|
|
@@ -162,7 +164,7 @@ guard_build() {
|
|
|
162
164
|
|
|
163
165
|
check "tasks.md all tasks checked" tasks_all_done
|
|
164
166
|
check "proposal.md exists" file_nonempty "$CHANGE_DIR/proposal.md"
|
|
165
|
-
check "
|
|
167
|
+
check "Build passes" build_passes
|
|
166
168
|
}
|
|
167
169
|
|
|
168
170
|
guard_verify() {
|
|
@@ -170,7 +172,7 @@ guard_verify() {
|
|
|
170
172
|
|
|
171
173
|
check "verify_result is pass" verify_result_is_pass
|
|
172
174
|
check "tasks.md all tasks checked" tasks_all_done
|
|
173
|
-
check "
|
|
175
|
+
check "Build passes" build_passes
|
|
174
176
|
}
|
|
175
177
|
|
|
176
178
|
guard_archive() {
|
|
@@ -182,7 +184,7 @@ guard_archive() {
|
|
|
182
184
|
}
|
|
183
185
|
|
|
184
186
|
apply_state_update() {
|
|
185
|
-
local state_sh="$
|
|
187
|
+
local state_sh="$script_dir/comet-state.sh"
|
|
186
188
|
local p="$1"
|
|
187
189
|
|
|
188
190
|
if [ -f "$state_sh" ]; then
|