specweave 1.0.256 → 1.0.259
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.md +56 -221
- package/README.md +31 -0
- package/bin/specweave.js +17 -0
- package/dist/src/adapters/README.md +4 -4
- package/dist/src/adapters/agents-md-generator.d.ts.map +1 -1
- package/dist/src/adapters/agents-md-generator.js +0 -2
- package/dist/src/adapters/agents-md-generator.js.map +1 -1
- package/dist/src/adapters/claude/README.md +3 -3
- package/dist/src/adapters/claude/adapter.js +3 -3
- package/dist/src/adapters/claude-md-generator.js +1 -1
- package/dist/src/adapters/claude-md-generator.js.map +1 -1
- package/dist/src/adapters/registry.yaml +1 -1
- package/dist/src/cli/commands/create-increment.d.ts +24 -0
- package/dist/src/cli/commands/create-increment.d.ts.map +1 -0
- package/dist/src/cli/commands/create-increment.js +53 -0
- package/dist/src/cli/commands/create-increment.js.map +1 -0
- package/dist/src/cli/commands/init.d.ts.map +1 -1
- package/dist/src/cli/commands/init.js +48 -31
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/update.d.ts.map +1 -1
- package/dist/src/cli/commands/update.js +36 -0
- package/dist/src/cli/commands/update.js.map +1 -1
- package/dist/src/cli/helpers/init/directory-structure.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/directory-structure.js +13 -1
- package/dist/src/cli/helpers/init/directory-structure.js.map +1 -1
- package/dist/src/cli/helpers/init/summary-banner.d.ts +11 -0
- package/dist/src/cli/helpers/init/summary-banner.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/summary-banner.js +49 -3
- package/dist/src/cli/helpers/init/summary-banner.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/index.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/index.js +0 -1
- package/dist/src/cli/helpers/issue-tracker/index.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/sync-config-writer.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/sync-config-writer.js +6 -2
- package/dist/src/cli/helpers/issue-tracker/sync-config-writer.js.map +1 -1
- package/dist/src/core/ac-progress-sync.d.ts +13 -0
- package/dist/src/core/ac-progress-sync.d.ts.map +1 -1
- package/dist/src/core/ac-progress-sync.js +28 -0
- package/dist/src/core/ac-progress-sync.js.map +1 -1
- package/dist/src/core/config/types.d.ts +24 -1
- package/dist/src/core/config/types.d.ts.map +1 -1
- package/dist/src/core/config/types.js +6 -1
- package/dist/src/core/config/types.js.map +1 -1
- package/dist/src/core/doctor/checkers/project-structure-checker.d.ts +1 -0
- package/dist/src/core/doctor/checkers/project-structure-checker.d.ts.map +1 -1
- package/dist/src/core/doctor/checkers/project-structure-checker.js +53 -3
- package/dist/src/core/doctor/checkers/project-structure-checker.js.map +1 -1
- package/dist/src/core/fabric/security-scanner.d.ts.map +1 -1
- package/dist/src/core/fabric/security-scanner.js +70 -9
- package/dist/src/core/fabric/security-scanner.js.map +1 -1
- package/dist/src/core/increment/increment-utils.d.ts +6 -0
- package/dist/src/core/increment/increment-utils.d.ts.map +1 -1
- package/dist/src/core/increment/increment-utils.js +5 -0
- package/dist/src/core/increment/increment-utils.js.map +1 -1
- package/dist/src/core/living-docs/discovery.d.ts +2 -0
- package/dist/src/core/living-docs/discovery.d.ts.map +1 -1
- package/dist/src/core/living-docs/discovery.js +91 -17
- package/dist/src/core/living-docs/discovery.js.map +1 -1
- package/dist/src/core/living-docs/intelligent-analyzer/index.d.ts +5 -0
- package/dist/src/core/living-docs/intelligent-analyzer/index.d.ts.map +1 -1
- package/dist/src/core/living-docs/intelligent-analyzer/index.js +3 -3
- package/dist/src/core/living-docs/intelligent-analyzer/index.js.map +1 -1
- package/dist/src/core/living-docs/lsp-bootstrapper.d.ts +64 -0
- package/dist/src/core/living-docs/lsp-bootstrapper.d.ts.map +1 -0
- package/dist/src/core/living-docs/lsp-bootstrapper.js +118 -0
- package/dist/src/core/living-docs/lsp-bootstrapper.js.map +1 -0
- package/dist/src/core/project/project-service.d.ts +10 -1
- package/dist/src/core/project/project-service.d.ts.map +1 -1
- package/dist/src/core/project/project-service.js +37 -2
- package/dist/src/core/project/project-service.js.map +1 -1
- package/dist/src/core/universal-auto-create.d.ts +64 -0
- package/dist/src/core/universal-auto-create.d.ts.map +1 -0
- package/dist/src/core/universal-auto-create.js +228 -0
- package/dist/src/core/universal-auto-create.js.map +1 -0
- package/package.json +1 -1
- package/plugins/specweave/PLUGIN.md +0 -3
- package/plugins/specweave/commands/living-docs.md +0 -2
- package/plugins/specweave/hooks/stop-sync.sh +34 -5
- package/plugins/specweave/hooks/user-prompt-submit.sh +115 -326
- package/plugins/specweave/hooks/v2/dispatchers/post-tool-use.sh +19 -5
- package/plugins/specweave/hooks/v2/handlers/ac-sync-dispatcher.sh +14 -4
- package/plugins/specweave/hooks/v2/handlers/universal-auto-create-dispatcher.sh +181 -0
- package/plugins/specweave/lib/hooks/sync-living-docs.js +4 -2
- package/plugins/specweave/scripts/skill-context.sh +160 -0
- package/plugins/specweave/skills/architect/SKILL.md +1 -1
- package/plugins/specweave/skills/archive-increments/SKILL.md +13 -3
- package/plugins/specweave/skills/auto/SKILL.md +92 -1038
- package/plugins/specweave/skills/do/SKILL.md +66 -1106
- package/plugins/specweave/skills/docs/SKILL.md +124 -56
- package/plugins/specweave/skills/done/SKILL.md +76 -1406
- package/plugins/specweave/skills/framework/SKILL.md +1 -1
- package/plugins/specweave/skills/increment/SKILL.md +1 -1
- package/plugins/specweave/skills/increment-planner/SKILL.md +29 -19
- package/plugins/specweave/skills/jobs/SKILL.md +52 -0
- package/plugins/specweave/skills/multi-project-spec-mapper/SKILL.md +1 -1
- package/plugins/specweave/skills/save/SKILL.md +51 -1372
- package/plugins/specweave/skills/smart-reopen-detector/SKILL.md +1 -1
- package/plugins/specweave/skills/tdd-orchestrator/SKILL.md +1 -1
- package/plugins/specweave/skills/validate/SKILL.md +65 -848
- package/plugins/specweave-backend/skills/database-optimizer/SKILL.md +1 -1
- package/plugins/specweave-backend/skills/graphql/SKILL.md +1 -1
- package/plugins/specweave-frontend/skills/design-system-architect/SKILL.md +1 -1
- package/plugins/specweave-frontend/skills/frontend/SKILL.md +1 -1
- package/plugins/specweave-frontend/skills/frontend-architect/SKILL.md +1 -1
- package/plugins/specweave-frontend/skills/frontend-design/SKILL.md +1 -1
- package/plugins/specweave-frontend/skills/i18n-expert/SKILL.md +1 -1
- package/plugins/specweave-payments/skills/billing-automation/SKILL.md +1 -1
- package/plugins/specweave-testing/skills/accessibility-testing/SKILL.md +1 -1
- package/src/templates/CLAUDE.md.template +50 -356
- package/src/templates/config.json.template +5 -1
- package/plugins/specweave/commands/brownfield-analyzer.md +0 -408
- package/plugins/specweave/commands/brownfield-onboarder.md +0 -837
- package/plugins/specweave/commands/export-skills.md +0 -179
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Universal Auto-Create Dispatcher (v1.0.256+)
|
|
3
|
+
#
|
|
4
|
+
# Creates per-user-story items in ALL enabled providers when spec.md is written.
|
|
5
|
+
# - GitHub: delegates to existing github-auto-create-handler.sh (backward compatible)
|
|
6
|
+
# - JIRA/ADO: calls src/core/universal-auto-create.ts via Node.js
|
|
7
|
+
#
|
|
8
|
+
# Usage: universal-auto-create-dispatcher.sh <INCREMENT_ID>
|
|
9
|
+
# Called by: safe_run_background in post-tool-use.sh
|
|
10
|
+
|
|
11
|
+
set +e # Never crash Claude Code
|
|
12
|
+
|
|
13
|
+
[[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]] && exit 0
|
|
14
|
+
|
|
15
|
+
# ============================================================================
|
|
16
|
+
# PROJECT ROOT
|
|
17
|
+
# ============================================================================
|
|
18
|
+
|
|
19
|
+
find_project_root() {
|
|
20
|
+
local dir="$1"
|
|
21
|
+
while [ "$dir" != "/" ]; do
|
|
22
|
+
[ -d "$dir/.specweave" ] && echo "$dir" && return 0
|
|
23
|
+
dir="$(dirname "$dir")"
|
|
24
|
+
done
|
|
25
|
+
return 1
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
PROJECT_ROOT="$(find_project_root "$(pwd)")"
|
|
29
|
+
[[ -z "$PROJECT_ROOT" ]] && exit 0
|
|
30
|
+
cd "$PROJECT_ROOT" 2>/dev/null || exit 0
|
|
31
|
+
|
|
32
|
+
# ============================================================================
|
|
33
|
+
# ARGUMENTS
|
|
34
|
+
# ============================================================================
|
|
35
|
+
|
|
36
|
+
INC_ID="$1"
|
|
37
|
+
[[ -z "$INC_ID" ]] && exit 0
|
|
38
|
+
[[ ! "$INC_ID" =~ ^[0-9]{4}[A-Za-z0-9_-]*$ ]] && exit 0
|
|
39
|
+
|
|
40
|
+
SPEC_PATH="$PROJECT_ROOT/.specweave/increments/$INC_ID/spec.md"
|
|
41
|
+
METADATA_PATH="$PROJECT_ROOT/.specweave/increments/$INC_ID/metadata.json"
|
|
42
|
+
CONFIG_PATH="$PROJECT_ROOT/.specweave/config.json"
|
|
43
|
+
|
|
44
|
+
[[ ! -f "$SPEC_PATH" ]] && exit 0
|
|
45
|
+
[[ ! -f "$CONFIG_PATH" ]] && exit 0
|
|
46
|
+
|
|
47
|
+
# ============================================================================
|
|
48
|
+
# LOGGING
|
|
49
|
+
# ============================================================================
|
|
50
|
+
|
|
51
|
+
LOGS_DIR="$PROJECT_ROOT/.specweave/logs"
|
|
52
|
+
LOG_FILE="$LOGS_DIR/universal-auto-create.log"
|
|
53
|
+
mkdir -p "$LOGS_DIR" 2>/dev/null || true
|
|
54
|
+
|
|
55
|
+
log() {
|
|
56
|
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [auto-create] $1" >> "$LOG_FILE" 2>/dev/null || true
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
# ============================================================================
|
|
60
|
+
# DEBOUNCE (10s window — spec.md gets edited rapidly during planning)
|
|
61
|
+
# ============================================================================
|
|
62
|
+
|
|
63
|
+
STATE_DIR="$PROJECT_ROOT/.specweave/state"
|
|
64
|
+
mkdir -p "$STATE_DIR" 2>/dev/null || true
|
|
65
|
+
DEBOUNCE_FILE="$STATE_DIR/.auto-create-pending-$INC_ID"
|
|
66
|
+
|
|
67
|
+
if [[ -f "$DEBOUNCE_FILE" ]]; then
|
|
68
|
+
if [[ "$(uname)" == "Darwin" ]]; then
|
|
69
|
+
AGE=$(($(date +%s) - $(stat -f%m "$DEBOUNCE_FILE" 2>/dev/null || echo 0)))
|
|
70
|
+
else
|
|
71
|
+
AGE=$(($(date +%s) - $(stat -c%Y "$DEBOUNCE_FILE" 2>/dev/null || echo 0)))
|
|
72
|
+
fi
|
|
73
|
+
[[ $AGE -lt 10 ]] && exit 0
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
echo "$(date +%s)" > "$DEBOUNCE_FILE" 2>/dev/null || true
|
|
77
|
+
sleep 10
|
|
78
|
+
|
|
79
|
+
# After sleeping, check if a newer invocation took over
|
|
80
|
+
if [[ -f "$DEBOUNCE_FILE" ]]; then
|
|
81
|
+
CURRENT_SIGNAL=$(cat "$DEBOUNCE_FILE" 2>/dev/null || echo 0)
|
|
82
|
+
SIGNAL_AGE=$(( $(date +%s) - CURRENT_SIGNAL ))
|
|
83
|
+
(( SIGNAL_AGE > 11 )) && exit 0
|
|
84
|
+
fi
|
|
85
|
+
rm -f "$DEBOUNCE_FILE" 2>/dev/null || true
|
|
86
|
+
|
|
87
|
+
# ============================================================================
|
|
88
|
+
# CHECK PROVIDERS
|
|
89
|
+
# ============================================================================
|
|
90
|
+
|
|
91
|
+
command -v jq >/dev/null 2>&1 || exit 0
|
|
92
|
+
|
|
93
|
+
GH_ENABLED=$(jq -r '.sync.github.enabled // false' "$CONFIG_PATH" 2>/dev/null)
|
|
94
|
+
JIRA_ENABLED=$(jq -r '.sync.jira.enabled // false' "$CONFIG_PATH" 2>/dev/null)
|
|
95
|
+
ADO_ENABLED=$(jq -r '.sync.ado.enabled // false' "$CONFIG_PATH" 2>/dev/null)
|
|
96
|
+
|
|
97
|
+
if [[ "$GH_ENABLED" != "true" && "$JIRA_ENABLED" != "true" && "$ADO_ENABLED" != "true" ]]; then
|
|
98
|
+
log "No providers enabled. Skipping."
|
|
99
|
+
exit 0
|
|
100
|
+
fi
|
|
101
|
+
|
|
102
|
+
# Check auto-create is enabled
|
|
103
|
+
AUTO_CREATE=$(jq -r '.sync.autoCreateOnIncrement // .sync.autoSync // .hooks.post_increment_planning.auto_create_github_issue // false' "$CONFIG_PATH" 2>/dev/null)
|
|
104
|
+
if [[ "$AUTO_CREATE" != "true" ]]; then
|
|
105
|
+
log "Auto-create disabled in config. Skipping."
|
|
106
|
+
exit 0
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
log "Creating external items for $INC_ID (github=$GH_ENABLED jira=$JIRA_ENABLED ado=$ADO_ENABLED)"
|
|
110
|
+
|
|
111
|
+
# ============================================================================
|
|
112
|
+
# GITHUB: Delegate to existing handler (backward compatible)
|
|
113
|
+
# ============================================================================
|
|
114
|
+
|
|
115
|
+
if [[ "$GH_ENABLED" == "true" ]]; then
|
|
116
|
+
GITHUB_HANDLER="${PROJECT_ROOT}/plugins/specweave-github/hooks/github-auto-create-handler.sh"
|
|
117
|
+
if [[ -f "$GITHUB_HANDLER" ]]; then
|
|
118
|
+
log "Delegating GitHub auto-create to existing handler"
|
|
119
|
+
bash "$GITHUB_HANDLER" "$INC_ID" &
|
|
120
|
+
GH_PID=$!
|
|
121
|
+
else
|
|
122
|
+
log "GitHub handler not found: $GITHUB_HANDLER"
|
|
123
|
+
fi
|
|
124
|
+
fi
|
|
125
|
+
|
|
126
|
+
# ============================================================================
|
|
127
|
+
# JIRA/ADO: Call TypeScript module for per-user-story creation
|
|
128
|
+
# ============================================================================
|
|
129
|
+
|
|
130
|
+
if [[ "$JIRA_ENABLED" == "true" || "$ADO_ENABLED" == "true" ]]; then
|
|
131
|
+
command -v node &>/dev/null || { log "Node.js not found. Skipping JIRA/ADO."; exit 0; }
|
|
132
|
+
|
|
133
|
+
CREATE_MODULE="$PROJECT_ROOT/dist/src/core/universal-auto-create.js"
|
|
134
|
+
if [[ ! -f "$CREATE_MODULE" ]]; then
|
|
135
|
+
log "Module not found at $CREATE_MODULE. Skipping JIRA/ADO."
|
|
136
|
+
else
|
|
137
|
+
# Build config JSON for the TypeScript module
|
|
138
|
+
JIRA_DOMAIN=$(jq -r '.sync.jira.domain // .issueTracker.domain // ""' "$CONFIG_PATH" 2>/dev/null)
|
|
139
|
+
JIRA_PROJECT_KEY=$(jq -r '.sync.jira.projectKey // .issueTracker.projects[0].key // ""' "$CONFIG_PATH" 2>/dev/null)
|
|
140
|
+
ADO_ORG=$(jq -r '.sync.ado.organization // .issueTracker.organization_ado // ""' "$CONFIG_PATH" 2>/dev/null)
|
|
141
|
+
ADO_PROJECT=$(jq -r '.sync.ado.project // .issueTracker.project // ""' "$CONFIG_PATH" 2>/dev/null)
|
|
142
|
+
|
|
143
|
+
OUTPUT=$(node --input-type=module -e "
|
|
144
|
+
import { createExternalIssuesForIncrement } from '${CREATE_MODULE}';
|
|
145
|
+
|
|
146
|
+
const config = {
|
|
147
|
+
sync: {
|
|
148
|
+
jira: { enabled: ${JIRA_ENABLED} },
|
|
149
|
+
ado: { enabled: ${ADO_ENABLED} },
|
|
150
|
+
},
|
|
151
|
+
jira: { domain: '${JIRA_DOMAIN}', projectKey: '${JIRA_PROJECT_KEY}' },
|
|
152
|
+
ado: { organization: '${ADO_ORG}', project: '${ADO_PROJECT}' },
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
try {
|
|
156
|
+
const result = await createExternalIssuesForIncrement(
|
|
157
|
+
'${INC_ID}', '${SPEC_PATH}', '${METADATA_PATH}', config,
|
|
158
|
+
);
|
|
159
|
+
console.log(JSON.stringify(result, null, 2));
|
|
160
|
+
} catch (err) {
|
|
161
|
+
console.error('Universal auto-create error:', err.message || err);
|
|
162
|
+
process.exit(1);
|
|
163
|
+
}
|
|
164
|
+
" 2>&1)
|
|
165
|
+
EXIT_CODE=$?
|
|
166
|
+
|
|
167
|
+
if [[ $EXIT_CODE -ne 0 ]]; then
|
|
168
|
+
log "JIRA/ADO creation failed (exit $EXIT_CODE): $OUTPUT"
|
|
169
|
+
else
|
|
170
|
+
log "JIRA/ADO creation completed: $OUTPUT"
|
|
171
|
+
fi
|
|
172
|
+
fi
|
|
173
|
+
fi
|
|
174
|
+
|
|
175
|
+
# Wait for GitHub handler if started
|
|
176
|
+
if [[ -n "${GH_PID:-}" ]]; then
|
|
177
|
+
wait "$GH_PID" 2>/dev/null || true
|
|
178
|
+
fi
|
|
179
|
+
|
|
180
|
+
log "Universal auto-create finished for $INC_ID"
|
|
181
|
+
exit 0
|
|
@@ -27,10 +27,12 @@ async function syncLivingDocs(incrementId) {
|
|
|
27
27
|
console.error(" To fix: Check .specweave/config.json for syntax errors");
|
|
28
28
|
config = { sync: { settings: {} } };
|
|
29
29
|
}
|
|
30
|
-
const syncEnabled = config.hooks?.
|
|
30
|
+
const syncEnabled = config.hooks?.post_increment_done?.sync_living_docs
|
|
31
|
+
?? config.hooks?.post_task_completion?.sync_living_docs // legacy fallback
|
|
32
|
+
?? false;
|
|
31
33
|
if (!syncEnabled) {
|
|
32
34
|
console.log("\u2139\uFE0F Living docs sync disabled in config");
|
|
33
|
-
console.log(" To enable: Set hooks.
|
|
35
|
+
console.log(" To enable: Set hooks.post_increment_done.sync_living_docs = true");
|
|
34
36
|
return;
|
|
35
37
|
}
|
|
36
38
|
console.log("\u2705 Living docs sync enabled");
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# skill-context.sh — Project context loader for DCI blocks
|
|
3
|
+
#
|
|
4
|
+
# Usage: .specweave/scripts/skill-context.sh [skill-name]
|
|
5
|
+
# Output: Key-value pairs grouped by section ([config], [project], [increment])
|
|
6
|
+
# Exit: Always 0 (graceful degradation)
|
|
7
|
+
#
|
|
8
|
+
# Performance: <100ms target. Single jq call for config, grep for metadata.
|
|
9
|
+
# Skill name argument is reserved for future skill-specific filtering.
|
|
10
|
+
|
|
11
|
+
CONFIG=".specweave/config.json"
|
|
12
|
+
HAS_JQ=false
|
|
13
|
+
command -v jq >/dev/null 2>&1 && HAS_JQ=true
|
|
14
|
+
|
|
15
|
+
# --- Parse all config values in ONE jq call ---
|
|
16
|
+
# ASSUMPTION: No config value contains literal '|' (pipe).
|
|
17
|
+
# If this changes, switch to per-field jq calls (~120ms slower).
|
|
18
|
+
_test_mode="" _test_enforce="" _deep_interview="" _auto_max=""
|
|
19
|
+
_multi_project="" _org=""
|
|
20
|
+
|
|
21
|
+
if [ -f "$CONFIG" ]; then
|
|
22
|
+
if $HAS_JQ; then
|
|
23
|
+
_raw=$(jq -r '
|
|
24
|
+
def v: if . == null then "" else tostring end;
|
|
25
|
+
[
|
|
26
|
+
(.testing.defaultTestMode | v),
|
|
27
|
+
(.testing.tddEnforcement | v),
|
|
28
|
+
(.planning.deepInterview.enabled | v),
|
|
29
|
+
(.auto.maxRetries | v),
|
|
30
|
+
(.multiProject.enabled | v),
|
|
31
|
+
(.sync.github.owner | v)
|
|
32
|
+
] | join("|")
|
|
33
|
+
' "$CONFIG" 2>/dev/null) || _raw=""
|
|
34
|
+
|
|
35
|
+
IFS='|' read -r _test_mode _test_enforce _deep_interview _auto_max _multi_project _org <<EOF
|
|
36
|
+
$_raw
|
|
37
|
+
EOF
|
|
38
|
+
else
|
|
39
|
+
# grep fallback (best-effort, no jq available)
|
|
40
|
+
# sed strips key prefix, quotes, and whitespace to extract raw value
|
|
41
|
+
_test_mode=$(grep -o '"defaultTestMode"[^,}]*' "$CONFIG" 2>/dev/null | head -1 | sed 's/[^:]*:[[:space:]]*//;s/^"//;s/"$//')
|
|
42
|
+
_test_enforce=$(grep -o '"tddEnforcement"[^,}]*' "$CONFIG" 2>/dev/null | head -1 | sed 's/[^:]*:[[:space:]]*//;s/^"//;s/"$//')
|
|
43
|
+
_auto_max=$(grep -o '"maxRetries"[^,}]*' "$CONFIG" 2>/dev/null | head -1 | sed 's/[^:]*:[[:space:]]*//;s/[^0-9]//g')
|
|
44
|
+
_org=$(grep -o '"owner"[^,}]*' "$CONFIG" 2>/dev/null | head -1 | sed 's/[^:]*:[[:space:]]*//;s/^"//;s/"$//')
|
|
45
|
+
fi
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
# --- [config] section ---
|
|
49
|
+
emit_config() {
|
|
50
|
+
[ -f "$CONFIG" ] || return 0
|
|
51
|
+
|
|
52
|
+
# Only emit header if at least one field has a value
|
|
53
|
+
[ -n "$_test_mode" ] || [ -n "$_test_enforce" ] || \
|
|
54
|
+
[ -n "$_deep_interview" ] || [ -n "$_auto_max" ] || return 0
|
|
55
|
+
|
|
56
|
+
echo "[config]"
|
|
57
|
+
[ -n "$_test_mode" ] && echo "testing.mode=$_test_mode"
|
|
58
|
+
[ -n "$_test_enforce" ] && echo "testing.enforcement=$_test_enforce"
|
|
59
|
+
[ -n "$_deep_interview" ] && echo "planning.deepInterview=$_deep_interview"
|
|
60
|
+
[ -n "$_auto_max" ] && echo "auto.maxIterations=$_auto_max"
|
|
61
|
+
|
|
62
|
+
return 0
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
# --- [project] section ---
|
|
66
|
+
emit_project() {
|
|
67
|
+
tech=""
|
|
68
|
+
|
|
69
|
+
# Detect from filesystem markers (builtins only, no subprocesses)
|
|
70
|
+
[ -f "package.json" ] && tech="${tech}node,"
|
|
71
|
+
[ -f "tsconfig.json" ] && tech="${tech}typescript,"
|
|
72
|
+
{ [ -f "requirements.txt" ] || [ -f "pyproject.toml" ]; } && tech="${tech}python,"
|
|
73
|
+
[ -f "go.mod" ] && tech="${tech}go,"
|
|
74
|
+
[ -f "Cargo.toml" ] && tech="${tech}rust,"
|
|
75
|
+
{ [ -f "pom.xml" ] || [ -f "build.gradle" ]; } && tech="${tech}java,"
|
|
76
|
+
|
|
77
|
+
# Shell glob for C# — no subprocess needed
|
|
78
|
+
_saved="$1"
|
|
79
|
+
_found_cs=false
|
|
80
|
+
set -- *.csproj
|
|
81
|
+
[ -e "$1" ] && _found_cs=true
|
|
82
|
+
set -- *.sln
|
|
83
|
+
[ -e "$1" ] && _found_cs=true
|
|
84
|
+
$_found_cs && tech="${tech}csharp,"
|
|
85
|
+
set -- "$_saved"
|
|
86
|
+
|
|
87
|
+
# Detect React/Next/Vue from package.json (one grep each, fast)
|
|
88
|
+
if [ -f "package.json" ]; then
|
|
89
|
+
grep -q '"react"' package.json 2>/dev/null && tech="${tech}react,"
|
|
90
|
+
grep -q '"next"' package.json 2>/dev/null && tech="${tech}nextjs,"
|
|
91
|
+
grep -q '"vue"' package.json 2>/dev/null && tech="${tech}vue,"
|
|
92
|
+
fi
|
|
93
|
+
|
|
94
|
+
# Strip trailing comma
|
|
95
|
+
tech="${tech%,}"
|
|
96
|
+
|
|
97
|
+
# Use pre-parsed config values (no extra subprocess)
|
|
98
|
+
multi="false"
|
|
99
|
+
[ "$_multi_project" = "true" ] && multi="true"
|
|
100
|
+
|
|
101
|
+
[ -z "$tech" ] && [ "$multi" = "false" ] && [ -z "$_org" ] && return 0
|
|
102
|
+
|
|
103
|
+
echo "[project]"
|
|
104
|
+
[ -n "$tech" ] && echo "tech=$tech"
|
|
105
|
+
echo "multi-repo=$multi"
|
|
106
|
+
[ -n "$_org" ] && echo "org=$_org"
|
|
107
|
+
|
|
108
|
+
return 0
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
# --- [increment] section ---
|
|
112
|
+
emit_increment() {
|
|
113
|
+
inc_dir=".specweave/increments"
|
|
114
|
+
[ -d "$inc_dir" ] || return 0
|
|
115
|
+
|
|
116
|
+
# Find active increment. Fast grep pre-filter eliminates non-candidates,
|
|
117
|
+
# then jq verifies precisely (handles single-line JSON, avoids false
|
|
118
|
+
# matches on previousStatus). Without jq, grep alone is best-effort.
|
|
119
|
+
active=""
|
|
120
|
+
for meta in "$inc_dir"/*/metadata.json; do
|
|
121
|
+
[ -f "$meta" ] || continue
|
|
122
|
+
# Fast pre-filter: skip files that don't mention in-progress at all
|
|
123
|
+
grep -q '"in-progress"' "$meta" 2>/dev/null || continue
|
|
124
|
+
# Precise check: jq validates the status field specifically
|
|
125
|
+
if $HAS_JQ; then
|
|
126
|
+
jq -e '.status == "in-progress"' "$meta" >/dev/null 2>&1 || continue
|
|
127
|
+
fi
|
|
128
|
+
active=$(basename "$(dirname "$meta")")
|
|
129
|
+
break
|
|
130
|
+
done
|
|
131
|
+
|
|
132
|
+
[ -z "$active" ] && return 0
|
|
133
|
+
|
|
134
|
+
# Calculate completion from tasks.md
|
|
135
|
+
completion=""
|
|
136
|
+
tasks_file="$inc_dir/$active/tasks.md"
|
|
137
|
+
if [ -f "$tasks_file" ]; then
|
|
138
|
+
total=$(grep -c '^\- \[' "$tasks_file" 2>/dev/null) || true
|
|
139
|
+
done_count=$(grep -c '^\- \[x\]' "$tasks_file" 2>/dev/null) || true
|
|
140
|
+
total=${total:-0}
|
|
141
|
+
done_count=${done_count:-0}
|
|
142
|
+
if [ "$total" -gt 0 ] 2>/dev/null; then
|
|
143
|
+
completion=$((done_count * 100 / total))
|
|
144
|
+
fi
|
|
145
|
+
fi
|
|
146
|
+
|
|
147
|
+
echo "[increment]"
|
|
148
|
+
echo "active=$active"
|
|
149
|
+
echo "status=in-progress"
|
|
150
|
+
[ -n "$completion" ] && echo "completion=${completion}%"
|
|
151
|
+
|
|
152
|
+
return 0
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
# --- Main ---
|
|
156
|
+
emit_config
|
|
157
|
+
emit_project
|
|
158
|
+
emit_increment
|
|
159
|
+
|
|
160
|
+
exit 0
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: System architect for scalable
|
|
2
|
+
description: System architect for scalable technical designs and ADRs. Use for system architecture, microservices, database design, trade-off analysis, component diagrams, tech selection.
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
# Architect
|
|
@@ -22,11 +22,20 @@ Expert at keeping the `.specweave/increments/` folder clean and organized throug
|
|
|
22
22
|
.specweave/increments/
|
|
23
23
|
├── 0023-0032 (Active) ← Last 10 increments
|
|
24
24
|
├── _archive/ ← Completed/old increments
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
└──
|
|
25
|
+
├── _abandoned/ ← Failed/obsolete increments
|
|
26
|
+
├── _paused/ ← Paused increments (blocked on dependency)
|
|
27
|
+
└── _backlog/ ← Planned but not started (future work)
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
+
Only these 4 underscore folders are recognized lifecycle folders. Unknown folders (e.g. `_analysis`, `_temp`) are flagged by `specweave doctor` and auto-cleaned by `specweave update`.
|
|
31
|
+
|
|
32
|
+
### Auto-Archive Trigger (v1.0.257+)
|
|
33
|
+
|
|
34
|
+
When `archiving.autoArchiveThreshold` (default: 10) numbered increment directories exist:
|
|
35
|
+
- **Interactive mode**: LLM is prompted to suggest `specweave archive --keep-last 10`
|
|
36
|
+
- **Auto mode**: Archiving runs automatically in the background
|
|
37
|
+
- **Rate-limited**: Once per day to avoid noise
|
|
38
|
+
|
|
30
39
|
### Smart Detection Rules
|
|
31
40
|
|
|
32
41
|
#### Never Archive
|
|
@@ -87,6 +96,7 @@ Expert at keeping the `.specweave/increments/` folder clean and organized throug
|
|
|
87
96
|
"archiving": {
|
|
88
97
|
"keepLast": 10, // Keep last 10 increments
|
|
89
98
|
"autoArchive": false, // Manual by default
|
|
99
|
+
"autoArchiveThreshold": 10, // Suggest archive when >= 10 increments
|
|
90
100
|
"archiveAfterDays": 60, // Archive after 60 days
|
|
91
101
|
"preserveActive": true, // Never archive active
|
|
92
102
|
"archiveCompleted": false // Manual control
|