@rpamis/comet 0.2.7 → 0.2.9
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/README.md +98 -63
- package/assets/manifest.json +1 -0
- package/assets/skills/comet/scripts/comet-archive.sh +39 -1
- package/assets/skills/comet/scripts/comet-guard.sh +188 -1
- package/assets/skills/comet/scripts/comet-handoff.sh +261 -0
- package/assets/skills/comet/scripts/comet-state.sh +34 -3
- package/assets/skills/comet/scripts/comet-yaml-validate.sh +42 -1
- package/assets/skills-zh/comet/SKILL.md +13 -10
- package/assets/skills-zh/comet-design/SKILL.md +59 -9
- package/dist/cli/index.js +1 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +9 -3
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +10 -7
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/update.d.ts +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +13 -9
- package/dist/commands/update.js.map +1 -1
- package/dist/core/detect.d.ts +1 -1
- package/dist/core/detect.d.ts.map +1 -1
- package/dist/core/detect.js +19 -10
- package/dist/core/detect.js.map +1 -1
- package/dist/core/platforms.d.ts +4 -0
- package/dist/core/platforms.d.ts.map +1 -1
- package/dist/core/platforms.js +16 -1
- package/dist/core/platforms.js.map +1 -1
- package/dist/core/skills.d.ts +3 -2
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +3 -2
- package/dist/core/skills.js.map +1 -1
- package/dist/core/superpowers.d.ts.map +1 -1
- package/dist/core/superpowers.js +2 -1
- package/dist/core/superpowers.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Comet Handoff — creates machine-owned context packages between phases
|
|
3
|
+
# Usage: comet-handoff.sh <change-name> design --write [--full]
|
|
4
|
+
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
red() { echo -e "\033[31m$1\033[0m" >&2; }
|
|
8
|
+
green() { echo -e "\033[32m$1\033[0m" >&2; }
|
|
9
|
+
|
|
10
|
+
validate_change_name() {
|
|
11
|
+
local name="$1"
|
|
12
|
+
if [ -z "$name" ]; then
|
|
13
|
+
red "ERROR: Change name cannot be empty"
|
|
14
|
+
exit 1
|
|
15
|
+
fi
|
|
16
|
+
if [[ ! "$name" =~ ^[a-zA-Z0-9_-]+$ ]]; then
|
|
17
|
+
red "ERROR: Invalid change name: '$name'"
|
|
18
|
+
red "Valid characters: a-z, A-Z, 0-9, -, _"
|
|
19
|
+
exit 1
|
|
20
|
+
fi
|
|
21
|
+
if [[ "$name" =~ \.\. ]]; then
|
|
22
|
+
red "ERROR: Change name cannot contain '..' (path traversal not allowed)"
|
|
23
|
+
exit 1
|
|
24
|
+
fi
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
strip_wrapping_quotes() {
|
|
28
|
+
local value="$1"
|
|
29
|
+
case "$value" in
|
|
30
|
+
\"*\") printf '%s\n' "${value:1:${#value}-2}" ;;
|
|
31
|
+
\'*\') printf '%s\n' "${value:1:${#value}-2}" ;;
|
|
32
|
+
*) printf '%s\n' "$value" ;;
|
|
33
|
+
esac
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
strip_inline_comment() {
|
|
37
|
+
local value="$1"
|
|
38
|
+
printf '%s\n' "$value" | awk -v squote="'" '
|
|
39
|
+
{
|
|
40
|
+
out = ""
|
|
41
|
+
quote = ""
|
|
42
|
+
for (i = 1; i <= length($0); i++) {
|
|
43
|
+
c = substr($0, i, 1)
|
|
44
|
+
if (quote == "") {
|
|
45
|
+
if (c == "\"" || c == squote) {
|
|
46
|
+
quote = c
|
|
47
|
+
} else if (c == "#" && (i == 1 || substr($0, i - 1, 1) ~ /[[:space:]]/)) {
|
|
48
|
+
sub(/[[:space:]]+$/, "", out)
|
|
49
|
+
print out
|
|
50
|
+
next
|
|
51
|
+
}
|
|
52
|
+
} else if (c == quote) {
|
|
53
|
+
quote = ""
|
|
54
|
+
}
|
|
55
|
+
out = out c
|
|
56
|
+
}
|
|
57
|
+
print out
|
|
58
|
+
}
|
|
59
|
+
'
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
yaml_field_value() {
|
|
63
|
+
local field="$1"
|
|
64
|
+
local yaml="$CHANGE_DIR/.comet.yaml"
|
|
65
|
+
local value
|
|
66
|
+
value=$(grep "^${field}:" "$yaml" 2>/dev/null | sed "s/^${field}: *//" || true)
|
|
67
|
+
value=$(strip_inline_comment "$value")
|
|
68
|
+
strip_wrapping_quotes "$value"
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
hash_stream() {
|
|
72
|
+
if command -v sha256sum >/dev/null 2>&1; then
|
|
73
|
+
sha256sum | awk '{print $1}'
|
|
74
|
+
elif command -v shasum >/dev/null 2>&1; then
|
|
75
|
+
shasum -a 256 | awk '{print $1}'
|
|
76
|
+
else
|
|
77
|
+
red "ERROR: sha256sum or shasum is required"
|
|
78
|
+
exit 1
|
|
79
|
+
fi
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
hash_file() {
|
|
83
|
+
local file="$1"
|
|
84
|
+
if command -v sha256sum >/dev/null 2>&1; then
|
|
85
|
+
sha256sum "$file" | awk '{print $1}'
|
|
86
|
+
elif command -v shasum >/dev/null 2>&1; then
|
|
87
|
+
shasum -a 256 "$file" | awk '{print $1}'
|
|
88
|
+
else
|
|
89
|
+
red "ERROR: sha256sum or shasum is required"
|
|
90
|
+
exit 1
|
|
91
|
+
fi
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
source_files() {
|
|
95
|
+
printf '%s\n' "$CHANGE_DIR/proposal.md"
|
|
96
|
+
printf '%s\n' "$CHANGE_DIR/design.md"
|
|
97
|
+
printf '%s\n' "$CHANGE_DIR/tasks.md"
|
|
98
|
+
if [ -d "$CHANGE_DIR/specs" ]; then
|
|
99
|
+
find "$CHANGE_DIR/specs" -path '*/spec.md' -type f 2>/dev/null | sort
|
|
100
|
+
fi
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
compute_context_hash() {
|
|
104
|
+
source_files | while IFS= read -r file; do
|
|
105
|
+
if [ -f "$file" ]; then
|
|
106
|
+
printf 'path:%s\n' "$file"
|
|
107
|
+
printf 'sha256:%s\n' "$(hash_file "$file")"
|
|
108
|
+
fi
|
|
109
|
+
done | hash_stream
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
json_escape() {
|
|
113
|
+
printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g'
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
file_line_count() {
|
|
117
|
+
local file="$1"
|
|
118
|
+
wc -l < "$file" | tr -d ' '
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
write_file_excerpt() {
|
|
122
|
+
local file="$1"
|
|
123
|
+
local max_lines="$2"
|
|
124
|
+
local total_lines
|
|
125
|
+
total_lines=$(file_line_count "$file")
|
|
126
|
+
|
|
127
|
+
echo "## $file"
|
|
128
|
+
echo ""
|
|
129
|
+
echo "- Source: $file"
|
|
130
|
+
echo "- Lines: 1-$total_lines"
|
|
131
|
+
echo "- SHA256: $(hash_file "$file")"
|
|
132
|
+
echo ""
|
|
133
|
+
|
|
134
|
+
if [ "$HANDOFF_MODE" = "full" ] || [ "$total_lines" -le "$max_lines" ]; then
|
|
135
|
+
echo '```md'
|
|
136
|
+
cat "$file"
|
|
137
|
+
echo '```'
|
|
138
|
+
else
|
|
139
|
+
echo "[TRUNCATED]"
|
|
140
|
+
echo ""
|
|
141
|
+
echo '```md'
|
|
142
|
+
sed -n "1,${max_lines}p" "$file"
|
|
143
|
+
echo '```'
|
|
144
|
+
echo ""
|
|
145
|
+
echo "Full source: $file"
|
|
146
|
+
fi
|
|
147
|
+
echo ""
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
write_markdown_context() {
|
|
151
|
+
local output="$1"
|
|
152
|
+
{
|
|
153
|
+
echo "# Comet Design Handoff"
|
|
154
|
+
echo ""
|
|
155
|
+
echo "- Change: $CHANGE"
|
|
156
|
+
echo "- Phase: design"
|
|
157
|
+
echo "- Mode: $HANDOFF_MODE"
|
|
158
|
+
echo "- Context hash: $CONTEXT_HASH"
|
|
159
|
+
echo ""
|
|
160
|
+
echo "Generated-by: comet-handoff.sh"
|
|
161
|
+
echo ""
|
|
162
|
+
echo "OpenSpec remains the canonical capability spec. This handoff is a deterministic, source-traceable context pack, not an agent-authored summary."
|
|
163
|
+
echo ""
|
|
164
|
+
source_files | while IFS= read -r file; do
|
|
165
|
+
[ -f "$file" ] || continue
|
|
166
|
+
write_file_excerpt "$file" 80
|
|
167
|
+
done
|
|
168
|
+
} > "$output"
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
write_json_context() {
|
|
172
|
+
local output="$1"
|
|
173
|
+
{
|
|
174
|
+
echo "{"
|
|
175
|
+
echo " \"change\": \"$(json_escape "$CHANGE")\","
|
|
176
|
+
echo " \"phase\": \"design\","
|
|
177
|
+
echo " \"mode\": \"$HANDOFF_MODE\","
|
|
178
|
+
echo " \"canonical_spec\": \"openspec\","
|
|
179
|
+
echo " \"generated_by\": \"comet-handoff.sh\","
|
|
180
|
+
echo " \"context_hash\": \"$CONTEXT_HASH\","
|
|
181
|
+
echo " \"files\": ["
|
|
182
|
+
local first=1
|
|
183
|
+
while IFS= read -r file; do
|
|
184
|
+
[ -f "$file" ] || continue
|
|
185
|
+
if [ "$first" -eq 0 ]; then
|
|
186
|
+
echo ","
|
|
187
|
+
fi
|
|
188
|
+
first=0
|
|
189
|
+
printf ' { "path": "%s", "sha256": "%s" }' "$(json_escape "$file")" "$(hash_file "$file")"
|
|
190
|
+
done < <(source_files)
|
|
191
|
+
echo ""
|
|
192
|
+
echo " ]"
|
|
193
|
+
echo "}"
|
|
194
|
+
} > "$output"
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
CHANGE="${1:-}"
|
|
198
|
+
PHASE="${2:-}"
|
|
199
|
+
MODE="${3:-}"
|
|
200
|
+
FULL_FLAG="${4:-}"
|
|
201
|
+
|
|
202
|
+
validate_change_name "$CHANGE"
|
|
203
|
+
|
|
204
|
+
if [ "$PHASE" != "design" ] || [ "$MODE" != "--write" ]; then
|
|
205
|
+
red "Usage: comet-handoff.sh <change-name> design --write [--full]"
|
|
206
|
+
exit 1
|
|
207
|
+
fi
|
|
208
|
+
case "$FULL_FLAG" in
|
|
209
|
+
"") HANDOFF_MODE="compact" ;;
|
|
210
|
+
--full) HANDOFF_MODE="full" ;;
|
|
211
|
+
*)
|
|
212
|
+
red "Usage: comet-handoff.sh <change-name> design --write [--full]"
|
|
213
|
+
exit 1
|
|
214
|
+
;;
|
|
215
|
+
esac
|
|
216
|
+
|
|
217
|
+
CHANGE_DIR="openspec/changes/$CHANGE"
|
|
218
|
+
YAML="$CHANGE_DIR/.comet.yaml"
|
|
219
|
+
SCRIPT_DIR="$(dirname "$(readlink -f "$0" 2>/dev/null || echo "$0")" 2>/dev/null || dirname "$0")"
|
|
220
|
+
STATE_SH="$SCRIPT_DIR/comet-state.sh"
|
|
221
|
+
|
|
222
|
+
if [ ! -d "$CHANGE_DIR" ]; then
|
|
223
|
+
red "ERROR: change directory not found: $CHANGE_DIR"
|
|
224
|
+
exit 1
|
|
225
|
+
fi
|
|
226
|
+
if [ ! -f "$YAML" ]; then
|
|
227
|
+
red "ERROR: .comet.yaml not found at $YAML"
|
|
228
|
+
exit 1
|
|
229
|
+
fi
|
|
230
|
+
if [ "$(yaml_field_value phase)" != "design" ]; then
|
|
231
|
+
red "ERROR: design handoff requires phase: design"
|
|
232
|
+
exit 1
|
|
233
|
+
fi
|
|
234
|
+
|
|
235
|
+
for required in proposal.md design.md tasks.md; do
|
|
236
|
+
if [ ! -s "$CHANGE_DIR/$required" ]; then
|
|
237
|
+
red "ERROR: required OpenSpec artifact missing or empty: $CHANGE_DIR/$required"
|
|
238
|
+
exit 1
|
|
239
|
+
fi
|
|
240
|
+
done
|
|
241
|
+
|
|
242
|
+
HANDOFF_DIR="$CHANGE_DIR/.comet/handoff"
|
|
243
|
+
CONTEXT_JSON="$HANDOFF_DIR/design-context.json"
|
|
244
|
+
CONTEXT_MD="$HANDOFF_DIR/design-context.md"
|
|
245
|
+
mkdir -p "$HANDOFF_DIR"
|
|
246
|
+
|
|
247
|
+
CONTEXT_HASH="$(compute_context_hash)"
|
|
248
|
+
write_markdown_context "$CONTEXT_MD"
|
|
249
|
+
write_json_context "$CONTEXT_JSON"
|
|
250
|
+
|
|
251
|
+
if [ -x "$STATE_SH" ] || [ -f "$STATE_SH" ]; then
|
|
252
|
+
bash "$STATE_SH" set "$CHANGE" handoff_context "$CONTEXT_JSON" >/dev/null
|
|
253
|
+
bash "$STATE_SH" set "$CHANGE" handoff_hash "$CONTEXT_HASH" >/dev/null
|
|
254
|
+
else
|
|
255
|
+
red "ERROR: comet-state.sh not found; cannot record handoff fields"
|
|
256
|
+
exit 1
|
|
257
|
+
fi
|
|
258
|
+
|
|
259
|
+
green "[HANDOFF] wrote $CONTEXT_JSON"
|
|
260
|
+
green "[HANDOFF] wrote $CONTEXT_MD"
|
|
261
|
+
green "[HANDOFF] handoff_hash=$CONTEXT_HASH"
|
|
@@ -72,10 +72,37 @@ yaml_field() {
|
|
|
72
72
|
if [ -f "$yaml_file" ]; then
|
|
73
73
|
local value
|
|
74
74
|
value=$(grep "^${field}:" "$yaml_file" 2>/dev/null | sed "s/^${field}: *//" || true)
|
|
75
|
+
value=$(strip_inline_comment "$value")
|
|
75
76
|
strip_wrapping_quotes "$value"
|
|
76
77
|
fi
|
|
77
78
|
}
|
|
78
79
|
|
|
80
|
+
strip_inline_comment() {
|
|
81
|
+
local value="$1"
|
|
82
|
+
printf '%s\n' "$value" | awk -v squote="'" '
|
|
83
|
+
{
|
|
84
|
+
out = ""
|
|
85
|
+
quote = ""
|
|
86
|
+
for (i = 1; i <= length($0); i++) {
|
|
87
|
+
c = substr($0, i, 1)
|
|
88
|
+
if (quote == "") {
|
|
89
|
+
if (c == "\"" || c == squote) {
|
|
90
|
+
quote = c
|
|
91
|
+
} else if (c == "#" && (i == 1 || substr($0, i - 1, 1) ~ /[[:space:]]/)) {
|
|
92
|
+
sub(/[[:space:]]+$/, "", out)
|
|
93
|
+
print out
|
|
94
|
+
next
|
|
95
|
+
}
|
|
96
|
+
} else if (c == quote) {
|
|
97
|
+
quote = ""
|
|
98
|
+
}
|
|
99
|
+
out = out c
|
|
100
|
+
}
|
|
101
|
+
print out
|
|
102
|
+
}
|
|
103
|
+
'
|
|
104
|
+
}
|
|
105
|
+
|
|
79
106
|
strip_wrapping_quotes() {
|
|
80
107
|
local value="$1"
|
|
81
108
|
case "$value" in
|
|
@@ -224,12 +251,16 @@ cmd_set() {
|
|
|
224
251
|
|
|
225
252
|
# Validate field name
|
|
226
253
|
case "$field" in
|
|
227
|
-
workflow|phase|build_mode|isolation|verify_mode|verify_result|verification_report|branch_status|archived|design_doc|plan|verified_at|direct_override|build_command|verify_command)
|
|
254
|
+
workflow|phase|build_mode|isolation|verify_mode|verify_result|verification_report|branch_status|archived|design_doc|plan|verified_at|direct_override|build_command|verify_command|handoff_context|handoff_hash)
|
|
228
255
|
# Valid field
|
|
229
256
|
;;
|
|
230
257
|
*)
|
|
231
258
|
red "ERROR: Unknown field: '$field'" >&2
|
|
232
|
-
red "Valid fields:
|
|
259
|
+
red "Valid fields:" >&2
|
|
260
|
+
red " workflow, phase, design_doc, plan, build_mode, isolation," >&2
|
|
261
|
+
red " verify_mode, verify_result, verification_report, branch_status," >&2
|
|
262
|
+
red " verified_at, archived, direct_override, build_command," >&2
|
|
263
|
+
red " verify_command, handoff_context, handoff_hash" >&2
|
|
233
264
|
exit 1
|
|
234
265
|
;;
|
|
235
266
|
esac
|
|
@@ -263,7 +294,7 @@ cmd_set() {
|
|
|
263
294
|
direct_override)
|
|
264
295
|
validate_enum "$value" "true" "false"
|
|
265
296
|
;;
|
|
266
|
-
design_doc|plan|verification_report|verified_at|build_command|verify_command)
|
|
297
|
+
design_doc|plan|verification_report|verified_at|build_command|verify_command|handoff_context|handoff_hash)
|
|
267
298
|
# No validation for path fields, date fields, or project command strings
|
|
268
299
|
;;
|
|
269
300
|
esac
|
|
@@ -46,9 +46,36 @@ WARNINGS=0
|
|
|
46
46
|
field_value() {
|
|
47
47
|
local value
|
|
48
48
|
value=$(grep "^${1}:" "$YAML" 2>/dev/null | sed "s/^${1}: *//" || true)
|
|
49
|
+
value=$(strip_inline_comment "$value")
|
|
49
50
|
strip_wrapping_quotes "$value"
|
|
50
51
|
}
|
|
51
52
|
|
|
53
|
+
strip_inline_comment() {
|
|
54
|
+
local value="$1"
|
|
55
|
+
printf '%s\n' "$value" | awk -v squote="'" '
|
|
56
|
+
{
|
|
57
|
+
out = ""
|
|
58
|
+
quote = ""
|
|
59
|
+
for (i = 1; i <= length($0); i++) {
|
|
60
|
+
c = substr($0, i, 1)
|
|
61
|
+
if (quote == "") {
|
|
62
|
+
if (c == "\"" || c == squote) {
|
|
63
|
+
quote = c
|
|
64
|
+
} else if (c == "#" && (i == 1 || substr($0, i - 1, 1) ~ /[[:space:]]/)) {
|
|
65
|
+
sub(/[[:space:]]+$/, "", out)
|
|
66
|
+
print out
|
|
67
|
+
next
|
|
68
|
+
}
|
|
69
|
+
} else if (c == quote) {
|
|
70
|
+
quote = ""
|
|
71
|
+
}
|
|
72
|
+
out = out c
|
|
73
|
+
}
|
|
74
|
+
print out
|
|
75
|
+
}
|
|
76
|
+
'
|
|
77
|
+
}
|
|
78
|
+
|
|
52
79
|
strip_wrapping_quotes() {
|
|
53
80
|
local value="$1"
|
|
54
81
|
case "$value" in
|
|
@@ -107,6 +134,8 @@ archived=$(field_value "archived")
|
|
|
107
134
|
direct_override=$(field_value "direct_override")
|
|
108
135
|
design_doc=$(field_value "design_doc")
|
|
109
136
|
plan=$(field_value "plan")
|
|
137
|
+
handoff_context=$(field_value "handoff_context")
|
|
138
|
+
handoff_hash=$(field_value "handoff_hash")
|
|
110
139
|
|
|
111
140
|
validate_enum "workflow" "$workflow" "full hotfix tweak"
|
|
112
141
|
validate_enum "phase" "$phase" "open design build verify archive"
|
|
@@ -132,8 +161,20 @@ if [ -n "$plan" ] && [ "$plan" != "null" ]; then
|
|
|
132
161
|
fi
|
|
133
162
|
fi
|
|
134
163
|
|
|
164
|
+
if [ -n "$handoff_context" ] && [ "$handoff_context" != "null" ]; then
|
|
165
|
+
if [ ! -f "$handoff_context" ]; then
|
|
166
|
+
fail "handoff_context='$handoff_context' does not exist on disk"
|
|
167
|
+
fi
|
|
168
|
+
fi
|
|
169
|
+
|
|
170
|
+
if [ -n "$handoff_hash" ] && [ "$handoff_hash" != "null" ]; then
|
|
171
|
+
if [[ ! "$handoff_hash" =~ ^[a-f0-9]{64}$ ]]; then
|
|
172
|
+
fail "handoff_hash='$handoff_hash' is not a sha256 hex digest"
|
|
173
|
+
fi
|
|
174
|
+
fi
|
|
175
|
+
|
|
135
176
|
# --- Unknown keys check ---
|
|
136
|
-
KNOWN_KEYS="workflow phase design_doc plan build_mode isolation verify_mode verify_result verification_report branch_status verified_at archived direct_override build_command verify_command"
|
|
177
|
+
KNOWN_KEYS="workflow phase design_doc plan build_mode isolation verify_mode verify_result verification_report branch_status verified_at archived direct_override build_command verify_command handoff_context handoff_hash"
|
|
137
178
|
while IFS=: read -r key _; do
|
|
138
179
|
key="${key// /}"
|
|
139
180
|
[ -z "$key" ] && continue
|
|
@@ -201,10 +201,11 @@ Comet 脚本随 skill 包分发在 `comet/scripts/` 下。**不硬编码路径**
|
|
|
201
201
|
COMET_SEARCH_ROOTS=("." "$HOME/.claude/skills" "$HOME/.codex/skills" "$HOME/.cursor/skills")
|
|
202
202
|
COMET_GUARD="${COMET_GUARD:-$(find "${COMET_SEARCH_ROOTS[@]}" -path '*/comet/scripts/comet-guard.sh' -type f -print -quit 2>/dev/null)}"
|
|
203
203
|
COMET_STATE="${COMET_STATE:-$(find "${COMET_SEARCH_ROOTS[@]}" -path '*/comet/scripts/comet-state.sh' -type f -print -quit 2>/dev/null)}"
|
|
204
|
+
COMET_HANDOFF="${COMET_HANDOFF:-$(find "${COMET_SEARCH_ROOTS[@]}" -path '*/comet/scripts/comet-handoff.sh' -type f -print -quit 2>/dev/null)}"
|
|
204
205
|
COMET_ARCHIVE="${COMET_ARCHIVE:-$(find "${COMET_SEARCH_ROOTS[@]}" -path '*/comet/scripts/comet-archive.sh' -type f -print -quit 2>/dev/null)}"
|
|
205
206
|
|
|
206
207
|
# 脚本定位失败时停止流程
|
|
207
|
-
if [ -z "$COMET_GUARD" ] || [ -z "$COMET_STATE" ] || [ -z "$COMET_ARCHIVE" ]; then
|
|
208
|
+
if [ -z "$COMET_GUARD" ] || [ -z "$COMET_STATE" ] || [ -z "$COMET_HANDOFF" ] || [ -z "$COMET_ARCHIVE" ]; then
|
|
208
209
|
echo "ERROR: Comet scripts not found. Ensure the comet skill is installed." >&2
|
|
209
210
|
echo "Expected path pattern: */comet/scripts/comet-*.sh under project or platform skill directories" >&2
|
|
210
211
|
return 1
|
|
@@ -234,7 +235,7 @@ bash "$COMET_STATE" transition <archive-name> archived
|
|
|
234
235
|
bash "$COMET_ARCHIVE" <change-name>
|
|
235
236
|
```
|
|
236
237
|
|
|
237
|
-
加载 comet 后,agent
|
|
238
|
+
加载 comet 后,agent 应执行以上变量赋值一次,后续全程复用 `$COMET_GUARD`、`$COMET_STATE`、`$COMET_HANDOFF`、`$COMET_ARCHIVE`。
|
|
238
239
|
|
|
239
240
|
### 文件结构
|
|
240
241
|
|
|
@@ -248,6 +249,7 @@ openspec/ # OpenSpec — WHAT
|
|
|
248
249
|
│ │ ├── proposal.md # Why + What
|
|
249
250
|
│ │ ├── design.md # 高层架构决策
|
|
250
251
|
│ │ ├── specs/<capability>/spec.md # Delta 能力规格
|
|
252
|
+
│ │ ├── .comet/handoff/ # 脚本生成的阶段交接包
|
|
251
253
|
│ │ └── tasks.md # 任务清单
|
|
252
254
|
│ └── archive/YYYY-MM-DD-<name>/ # 已归档
|
|
253
255
|
└── specs/<capability>/spec.md # 主 specs(归档时从 delta 覆盖)
|
|
@@ -261,11 +263,12 @@ docs/superpowers/ # Superpowers — HOW
|
|
|
261
263
|
|
|
262
264
|
1. **brainstorming 不可跳过** — 每次变更必须经过深度设计(hotfix 和 tweak 除外)
|
|
263
265
|
2. **delta spec 是活文档** — 阶段 3 期间可自由修改,归档时同步
|
|
264
|
-
3.
|
|
265
|
-
4.
|
|
266
|
-
5.
|
|
267
|
-
6.
|
|
268
|
-
7.
|
|
269
|
-
8.
|
|
270
|
-
9.
|
|
271
|
-
10.
|
|
266
|
+
3. **交接包由脚本生成** — OpenSpec → Superpowers 的上下文必须通过 `comet-handoff.sh` 生成 compact 可追溯摘录(必要时 `--full`),并由 guard 校验 source/hash/mode
|
|
267
|
+
4. **保持 tasks.md 同步** — 完成一个勾一个
|
|
268
|
+
5. **频繁提交** — 每个任务一次提交,message 体现设计意图
|
|
269
|
+
6. **先验证再归档** — `/comet-verify` 通过后才执行 `/comet-archive`
|
|
270
|
+
7. **增量更新分级** — 小编辑、中重 brainstorming、大新 change
|
|
271
|
+
8. **Plan 必须关联 change** — 文件头包含 `change:` 和 `design-doc:` 元数据
|
|
272
|
+
9. **归档闭环** — design doc 和 plan 必须标注 `archived-with` 状态
|
|
273
|
+
10. **修改已有功能** — 直接 open 新 change 即可
|
|
274
|
+
11. **Preset 有上限** — hotfix/tweak 满足升级条件时及时切换到完整流程
|
|
@@ -20,16 +20,50 @@ description: "Comet 阶段 2:深度设计。用 /comet-design 调用。通过
|
|
|
20
20
|
COMET_SEARCH_ROOTS=("." "$HOME/.claude/skills" "$HOME/.codex/skills" "$HOME/.cursor/skills")
|
|
21
21
|
COMET_STATE="${COMET_STATE:-$(find "${COMET_SEARCH_ROOTS[@]}" -path '*/comet/scripts/comet-state.sh' -type f -print -quit 2>/dev/null)}"
|
|
22
22
|
COMET_GUARD="${COMET_GUARD:-$(find "${COMET_SEARCH_ROOTS[@]}" -path '*/comet/scripts/comet-guard.sh' -type f -print -quit 2>/dev/null)}"
|
|
23
|
+
COMET_HANDOFF="${COMET_HANDOFF:-$(find "${COMET_SEARCH_ROOTS[@]}" -path '*/comet/scripts/comet-handoff.sh' -type f -print -quit 2>/dev/null)}"
|
|
23
24
|
bash "$COMET_STATE" check <name> design
|
|
24
25
|
```
|
|
25
26
|
|
|
26
27
|
验证通过后继续 Step 1。验证失败时脚本会输出具体失败原因。
|
|
27
28
|
|
|
28
|
-
### 1a.
|
|
29
|
+
### 1a. 生成 OpenSpec → Superpowers 交接包
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
**必须由脚本生成,不允许 agent 临场手写 summary 代替。**
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
bash "$COMET_HANDOFF" <change-name> design --write
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
脚本会生成并记录:
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
openspec/changes/<name>/.comet/handoff/design-context.json
|
|
41
|
+
openspec/changes/<name>/.comet/handoff/design-context.md
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
并在 `.comet.yaml` 写入:
|
|
45
|
+
|
|
46
|
+
```yaml
|
|
47
|
+
handoff_context: openspec/changes/<name>/.comet/handoff/design-context.json
|
|
48
|
+
handoff_hash: <sha256>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
默认交接包是 **compact 可追溯摘录**,不是 agent summary:
|
|
52
|
+
- `design-context.json`:机器索引,包含 change、phase、canonical spec、source paths、hash
|
|
53
|
+
- `design-context.md`:供 Superpowers 阅读的上下文,包含脚本标记、source path、line range、sha256、确定性摘录
|
|
54
|
+
- 超出摘录预算时标记 `[TRUNCATED]`,并保留 Full source 路径
|
|
55
|
+
|
|
56
|
+
如确实需要全文上下文,可显式运行:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
bash "$COMET_HANDOFF" <change-name> design --write --full
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
交接包来源来自 OpenSpec open 阶段产物:
|
|
63
|
+
- `proposal.md`:目标、动机、范围、非目标
|
|
64
|
+
- `design.md`:高层架构决策、方案约束
|
|
65
|
+
- `tasks.md`:初始任务边界
|
|
66
|
+
- `specs/*/spec.md`:delta 能力规格
|
|
33
67
|
|
|
34
68
|
### 1b. 执行 Brainstorming(带上下文)
|
|
35
69
|
|
|
@@ -37,9 +71,21 @@ bash "$COMET_STATE" check <name> design
|
|
|
37
71
|
|
|
38
72
|
```
|
|
39
73
|
Change: <change-name>
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
74
|
+
OpenSpec Context Pack: openspec/changes/<name>/.comet/handoff/design-context.md
|
|
75
|
+
Machine handoff: openspec/changes/<name>/.comet/handoff/design-context.json
|
|
76
|
+
|
|
77
|
+
OpenSpec 产物是上游事实源,不要重新定义需求,不要重写 proposal/spec。
|
|
78
|
+
你的任务是基于交接包做深度技术设计:实现方案、技术风险、测试策略、边界条件。
|
|
79
|
+
如发现 OpenSpec delta spec 缺少验收场景,只能提出 Spec Patch,并回写 OpenSpec delta spec;不要在 Design Doc 中创建第二份需求 spec。
|
|
80
|
+
|
|
81
|
+
Design Doc frontmatter 必须最小化,只包含:
|
|
82
|
+
---
|
|
83
|
+
comet_change: <change-name>
|
|
84
|
+
role: technical-design
|
|
85
|
+
canonical_spec: openspec
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
跳过重复上下文探索,直接进入设计提问。
|
|
43
89
|
```
|
|
44
90
|
|
|
45
91
|
禁止跳过此步骤,禁止在未加载该技能的情况下继续。
|
|
@@ -48,7 +94,7 @@ Design 摘要: <design.md 架构决策>
|
|
|
48
94
|
|
|
49
95
|
技能加载后,按其指引产出:
|
|
50
96
|
- `docs/superpowers/specs/YYYY-MM-DD-<topic>-design.md` — 设计文档(技术 RFC)
|
|
51
|
-
- `openspec/changes/<name>/specs/<capability>/spec.md` —
|
|
97
|
+
- 如需补充验收场景,回写 `openspec/changes/<name>/specs/<capability>/spec.md` — OpenSpec delta 能力规格
|
|
52
98
|
|
|
53
99
|
### 2. 更新 Comet 状态
|
|
54
100
|
|
|
@@ -67,7 +113,11 @@ bash "$COMET_GUARD" <change-name> design --apply
|
|
|
67
113
|
## 退出条件
|
|
68
114
|
|
|
69
115
|
- Design Doc 已创建并保存
|
|
70
|
-
-
|
|
116
|
+
- Design Doc frontmatter 包含 `comet_change`、`role: technical-design`、`canonical_spec: openspec`
|
|
117
|
+
- `handoff_context` 和 `handoff_hash` 已写入 `.comet.yaml`(由 guard 强制校验)
|
|
118
|
+
- `handoff_hash` 与当前 OpenSpec open 阶段产物一致(由 guard 强制校验)
|
|
119
|
+
- `design-context.md` 必须是脚本生成,且包含 source path、mode、sha256 等可追溯标记(由 guard 强制校验)
|
|
120
|
+
- 如有新能力或补充验收场景,OpenSpec delta spec 已创建/更新
|
|
71
121
|
- `design_doc` 已写入 `.comet.yaml`
|
|
72
122
|
- **阶段守卫**:运行 `bash "$COMET_GUARD" <change-name> design --apply`,全部 PASS 后自动流转到 `phase: build`
|
|
73
123
|
|
package/dist/cli/index.js
CHANGED
|
@@ -18,6 +18,7 @@ program
|
|
|
18
18
|
.option('--skip-existing', 'Never overwrite existing components')
|
|
19
19
|
.option('--overwrite', 'Overwrite manifest-managed files')
|
|
20
20
|
.option('--json', 'Output as JSON')
|
|
21
|
+
.addOption(new Option('--scope <scope>', 'Install scope').choices(['global', 'project']))
|
|
21
22
|
.action(async (targetPath = '.', options) => {
|
|
22
23
|
try {
|
|
23
24
|
await initCommand(targetPath, options);
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAQrD,KAAK,WAAW,GAAG,YAAY,GAAG,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAQrD,KAAK,WAAW,GAAG,YAAY,GAAG,MAAM,CAAC;AAgNzC,UAAU,aAAa;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB;AAED,wBAAsB,aAAa,CACjC,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAiBf"}
|
package/dist/commands/doctor.js
CHANGED
|
@@ -5,7 +5,7 @@ import { promises as fs } from 'fs';
|
|
|
5
5
|
import { fileExists, readDir } from '../utils/file-system.js';
|
|
6
6
|
import { isCommandAvailable } from '../core/openspec.js';
|
|
7
7
|
import { readManifest, getAssetsDir } from '../core/skills.js';
|
|
8
|
-
import { PLATFORMS } from '../core/platforms.js';
|
|
8
|
+
import { PLATFORMS, getPlatformSkillsDirs } from '../core/platforms.js';
|
|
9
9
|
const VALID_YAML_FIELDS = new Set([
|
|
10
10
|
'workflow',
|
|
11
11
|
'phase',
|
|
@@ -79,13 +79,19 @@ async function checkSkillCompleteness(projectPath, scope) {
|
|
|
79
79
|
let anyPlatform = false;
|
|
80
80
|
for (const base of getScopeBases(projectPath, scope)) {
|
|
81
81
|
for (const platform of PLATFORMS) {
|
|
82
|
-
const
|
|
82
|
+
const detectedSkillsDir = (await Promise.all(getPlatformSkillsDirs(platform, base.scope).map(async (skillsDir) => ({
|
|
83
|
+
skillsDir,
|
|
84
|
+
exists: await fileExists(path.join(base.baseDir, skillsDir, 'skills')),
|
|
85
|
+
})))).find((candidate) => candidate.exists)?.skillsDir;
|
|
86
|
+
if (!detectedSkillsDir)
|
|
87
|
+
continue;
|
|
88
|
+
const skillsDir = path.join(base.baseDir, detectedSkillsDir, 'skills');
|
|
83
89
|
if (!(await fileExists(skillsDir)))
|
|
84
90
|
continue;
|
|
85
91
|
anyPlatform = true;
|
|
86
92
|
const missing = [];
|
|
87
93
|
for (const relPath of manifest.skills) {
|
|
88
|
-
const fullPath = path.join(base.baseDir,
|
|
94
|
+
const fullPath = path.join(base.baseDir, detectedSkillsDir, 'skills', relPath);
|
|
89
95
|
if (!(await fileExists(fullPath))) {
|
|
90
96
|
missing.push(relPath);
|
|
91
97
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/init.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { type InstallScope } from '../core/detect.js';
|
|
1
2
|
type InitOptions = {
|
|
2
3
|
yes?: boolean;
|
|
3
4
|
skipExisting?: boolean;
|
|
4
5
|
overwrite?: boolean;
|
|
5
6
|
json?: boolean;
|
|
7
|
+
scope?: InstallScope;
|
|
6
8
|
};
|
|
7
9
|
type ComponentAction = 'overwrite' | 'skip' | 'install';
|
|
8
10
|
type BulkOverwriteChoice = 'overwrite-all' | 'skip-all' | 'choose';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAIA,OAAO,EAA0C,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAS9F,KAAK,WAAW,GAAG;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB,CAAC;AAGF,KAAK,eAAe,GAAG,WAAW,GAAG,MAAM,GAAG,SAAS,CAAC;AACxD,KAAK,mBAAmB,GAAG,eAAe,GAAG,UAAU,GAAG,QAAQ,CAAC;AASnE,KAAK,aAAa,GAAG;IACnB,QAAQ,EAAE,eAAe,CAAC;IAC1B,QAAQ,EAAE,eAAe,CAAC;IAC1B,QAAQ,EAAE,eAAe,CAAC;CAC3B,CAAC;AAmFF,iBAAS,wBAAwB,CAAC,CAAC,SAAS,aAAa,EACvD,IAAI,EAAE,CAAC,EACP,MAAM,EAAE,OAAO,CAAC,mBAAmB,EAAE,QAAQ,CAAC,GAC7C,CAAC,CAQH;AAmDD,wBAAsB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyK9F;AAED,OAAO,EAAE,wBAAwB,EAAE,CAAC"}
|