@open-agent-toolkit/cli 0.2.35 → 0.2.37
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/assets/bundle-metadata.json +1 -1
- package/assets/docs/cli-utilities/backlog-lifecycle.md +18 -0
- package/assets/docs/cli-utilities/bootstrap.md +6 -3
- package/assets/docs/cli-utilities/config-and-local-state.md +26 -12
- package/assets/docs/cli-utilities/configuration.md +36 -13
- package/assets/docs/cli-utilities/tool-packs.md +423 -51
- package/assets/docs/provider-sync/scope-and-surface.md +4 -1
- package/assets/docs/reference/cli-reference.md +5 -3
- package/assets/docs/reference/file-locations.md +28 -4
- package/assets/docs/reference/troubleshooting.md +132 -2
- package/assets/docs/workflows/projects/lifecycle.md +21 -2
- package/assets/public-package-versions.json +4 -4
- package/assets/scripts/generate-oat-state.sh +441 -0
- package/assets/scripts/generate-thin-index.sh +200 -0
- package/assets/skills/oat-agent-instructions-analyze/SKILL.md +10 -5
- package/assets/skills/oat-agent-instructions-apply/SKILL.md +30 -5
- package/assets/skills/oat-brainstorm/SKILL.md +34 -8
- package/assets/skills/oat-brainstorm/references/destinations.md +6 -1
- package/assets/skills/oat-docs-analyze/SKILL.md +9 -4
- package/assets/skills/oat-docs-apply/SKILL.md +6 -3
- package/assets/skills/oat-pjm-add-backlog-item/SKILL.md +14 -1
- package/assets/skills/oat-pjm-decision/SKILL.md +22 -10
- package/assets/skills/oat-pjm-review-backlog/SKILL.md +20 -3
- package/assets/skills/oat-pjm-update-repo-reference/SKILL.md +20 -10
- package/assets/skills/oat-project-autonomous/references/gate-inventory.md +1 -1
- package/assets/skills/oat-project-document/SKILL.md +21 -3
- package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-summary/SKILL.md +23 -11
- package/assets/skills/oat-repo-knowledge-index/SKILL.md +6 -3
- package/dist/commands/backlog/index.d.ts +2 -0
- package/dist/commands/backlog/index.d.ts.map +1 -1
- package/dist/commands/backlog/index.js +67 -23
- package/dist/commands/backlog/new.d.ts +3 -0
- package/dist/commands/backlog/new.d.ts.map +1 -1
- package/dist/commands/backlog/new.js +8 -21
- package/dist/commands/decision/agents-guidance.d.ts.map +1 -1
- package/dist/commands/decision/agents-guidance.js +2 -1
- package/dist/commands/decision/index.d.ts +2 -0
- package/dist/commands/decision/index.d.ts.map +1 -1
- package/dist/commands/decision/index.js +19 -3
- package/dist/commands/decision/new.d.ts +4 -0
- package/dist/commands/decision/new.d.ts.map +1 -1
- package/dist/commands/decision/new.js +11 -30
- package/dist/commands/doctor/index.d.ts +4 -0
- package/dist/commands/doctor/index.d.ts.map +1 -1
- package/dist/commands/doctor/index.js +254 -9
- package/dist/commands/init/tools/brainstorm/index.d.ts.map +1 -1
- package/dist/commands/init/tools/brainstorm/index.js +20 -6
- package/dist/commands/init/tools/docs/index.d.ts.map +1 -1
- package/dist/commands/init/tools/docs/index.js +4 -1
- package/dist/commands/init/tools/ideas/index.d.ts.map +1 -1
- package/dist/commands/init/tools/ideas/index.js +4 -1
- package/dist/commands/init/tools/index.d.ts +11 -2
- package/dist/commands/init/tools/index.d.ts.map +1 -1
- package/dist/commands/init/tools/index.js +459 -351
- package/dist/commands/init/tools/install-state.d.ts +2 -0
- package/dist/commands/init/tools/install-state.d.ts.map +1 -1
- package/dist/commands/init/tools/install-state.js +11 -0
- package/dist/commands/init/tools/project-management/agents-guidance.d.ts.map +1 -1
- package/dist/commands/init/tools/project-management/agents-guidance.js +3 -1
- package/dist/commands/init/tools/project-management/index.d.ts +1 -0
- package/dist/commands/init/tools/project-management/index.d.ts.map +1 -1
- package/dist/commands/init/tools/project-management/index.js +24 -55
- package/dist/commands/init/tools/project-management/install-project-management.d.ts +4 -0
- package/dist/commands/init/tools/project-management/install-project-management.d.ts.map +1 -1
- package/dist/commands/init/tools/project-management/install-project-management.js +4 -1
- package/dist/commands/init/tools/research/index.d.ts.map +1 -1
- package/dist/commands/init/tools/research/index.js +4 -1
- package/dist/commands/init/tools/shared/copy-helpers.d.ts.map +1 -1
- package/dist/commands/init/tools/shared/copy-helpers.js +10 -0
- package/dist/commands/init/tools/shared/skill-manifest.d.ts +15 -15
- package/dist/commands/init/tools/shared/skill-manifest.d.ts.map +1 -1
- package/dist/commands/init/tools/shared/skill-manifest.js +17 -122
- package/dist/commands/init/tools/utility/index.d.ts.map +1 -1
- package/dist/commands/init/tools/utility/index.js +4 -1
- package/dist/commands/init/tools/workflows/index.d.ts.map +1 -1
- package/dist/commands/init/tools/workflows/index.js +4 -1
- package/dist/commands/init/tools/workflows/install-workflows.d.ts.map +1 -1
- package/dist/commands/init/tools/workflows/install-workflows.js +2 -4
- package/dist/commands/pjm/adoption.d.ts +12 -0
- package/dist/commands/pjm/adoption.d.ts.map +1 -0
- package/dist/commands/pjm/adoption.js +47 -0
- package/dist/commands/pjm/doctor.d.ts +3 -2
- package/dist/commands/pjm/doctor.d.ts.map +1 -1
- package/dist/commands/pjm/doctor.js +28 -13
- package/dist/commands/pjm/index.d.ts +2 -0
- package/dist/commands/pjm/index.d.ts.map +1 -1
- package/dist/commands/pjm/index.js +11 -3
- package/dist/commands/pjm/init.d.ts +3 -0
- package/dist/commands/pjm/init.d.ts.map +1 -1
- package/dist/commands/pjm/init.js +37 -32
- package/dist/commands/pjm/migrate.d.ts +1 -0
- package/dist/commands/pjm/migrate.d.ts.map +1 -1
- package/dist/commands/pjm/migrate.js +1 -0
- package/dist/commands/pjm/template-source.d.ts +14 -0
- package/dist/commands/pjm/template-source.d.ts.map +1 -0
- package/dist/commands/pjm/template-source.js +56 -0
- package/dist/commands/remove/skills/remove-skills.d.ts.map +1 -1
- package/dist/commands/remove/skills/remove-skills.js +10 -19
- package/dist/commands/status/index.d.ts +5 -0
- package/dist/commands/status/index.d.ts.map +1 -1
- package/dist/commands/status/index.js +203 -2
- package/dist/commands/sync/index.d.ts.map +1 -1
- package/dist/commands/sync/index.js +40 -7
- package/dist/commands/sync/sync.types.d.ts +4 -0
- package/dist/commands/sync/sync.types.d.ts.map +1 -1
- package/dist/commands/tools/has/has-pack.d.ts +11 -2
- package/dist/commands/tools/has/has-pack.d.ts.map +1 -1
- package/dist/commands/tools/has/has-pack.js +33 -20
- package/dist/commands/tools/index.d.ts.map +1 -1
- package/dist/commands/tools/index.js +3 -1
- package/dist/commands/tools/info/info-tool.d.ts +3 -0
- package/dist/commands/tools/info/info-tool.d.ts.map +1 -1
- package/dist/commands/tools/info/info-tool.js +29 -4
- package/dist/commands/tools/list/list-tools.d.ts +3 -0
- package/dist/commands/tools/list/list-tools.d.ts.map +1 -1
- package/dist/commands/tools/list/list-tools.js +31 -4
- package/dist/commands/tools/migrate/index.d.ts +26 -0
- package/dist/commands/tools/migrate/index.d.ts.map +1 -0
- package/dist/commands/tools/migrate/index.js +312 -0
- package/dist/commands/tools/migrate/migrate-pack.d.ts +81 -0
- package/dist/commands/tools/migrate/migrate-pack.d.ts.map +1 -0
- package/dist/commands/tools/migrate/migrate-pack.js +324 -0
- package/dist/commands/tools/outdated/outdated-tools.d.ts +11 -0
- package/dist/commands/tools/outdated/outdated-tools.d.ts.map +1 -1
- package/dist/commands/tools/outdated/outdated-tools.js +33 -5
- package/dist/commands/tools/remove/index.d.ts.map +1 -1
- package/dist/commands/tools/remove/index.js +73 -20
- package/dist/commands/tools/remove/remove-tools.d.ts +28 -0
- package/dist/commands/tools/remove/remove-tools.d.ts.map +1 -1
- package/dist/commands/tools/remove/remove-tools.js +156 -26
- package/dist/commands/tools/shared/apply-pack-reconcile.d.ts +41 -0
- package/dist/commands/tools/shared/apply-pack-reconcile.d.ts.map +1 -0
- package/dist/commands/tools/shared/apply-pack-reconcile.js +126 -0
- package/dist/commands/tools/shared/auto-sync.d.ts +5 -2
- package/dist/commands/tools/shared/auto-sync.d.ts.map +1 -1
- package/dist/commands/tools/shared/auto-sync.js +1 -0
- package/dist/commands/tools/shared/content-digest.d.ts +3 -0
- package/dist/commands/tools/shared/content-digest.d.ts.map +1 -0
- package/dist/commands/tools/shared/content-digest.js +57 -0
- package/dist/commands/tools/shared/format-pack-inventory.d.ts +3 -0
- package/dist/commands/tools/shared/format-pack-inventory.d.ts.map +1 -0
- package/dist/commands/tools/shared/format-pack-inventory.js +21 -0
- package/dist/commands/tools/shared/install-sync-context.d.ts.map +1 -1
- package/dist/commands/tools/shared/install-sync-context.js +2 -25
- package/dist/commands/tools/shared/pack-inventory.d.ts +46 -0
- package/dist/commands/tools/shared/pack-inventory.d.ts.map +1 -0
- package/dist/commands/tools/shared/pack-inventory.js +207 -0
- package/dist/commands/tools/shared/pack-lifecycle.d.ts +34 -0
- package/dist/commands/tools/shared/pack-lifecycle.d.ts.map +1 -0
- package/dist/commands/tools/shared/pack-lifecycle.js +67 -0
- package/dist/commands/tools/shared/pack-manifest.d.ts +11 -0
- package/dist/commands/tools/shared/pack-manifest.d.ts.map +1 -0
- package/dist/commands/tools/shared/pack-manifest.js +384 -0
- package/dist/commands/tools/shared/pack-paths.d.ts +21 -0
- package/dist/commands/tools/shared/pack-paths.d.ts.map +1 -0
- package/dist/commands/tools/shared/pack-paths.js +35 -0
- package/dist/commands/tools/shared/pack-reconcile.d.ts +64 -0
- package/dist/commands/tools/shared/pack-reconcile.d.ts.map +1 -0
- package/dist/commands/tools/shared/pack-reconcile.js +158 -0
- package/dist/commands/tools/shared/project-tools-config.d.ts.map +1 -1
- package/dist/commands/tools/shared/project-tools-config.js +12 -38
- package/dist/commands/tools/shared/scan-tools.js +2 -2
- package/dist/commands/tools/shared/scoped-pack-intent.d.ts +34 -0
- package/dist/commands/tools/shared/scoped-pack-intent.d.ts.map +1 -0
- package/dist/commands/tools/shared/scoped-pack-intent.js +116 -0
- package/dist/commands/tools/shared/types.d.ts +22 -0
- package/dist/commands/tools/shared/types.d.ts.map +1 -1
- package/dist/commands/tools/update/index.d.ts.map +1 -1
- package/dist/commands/tools/update/index.js +30 -5
- package/dist/commands/tools/update/update-tools.d.ts +9 -1
- package/dist/commands/tools/update/update-tools.d.ts.map +1 -1
- package/dist/commands/tools/update/update-tools.js +176 -64
- package/dist/config/oat-config.d.ts +6 -0
- package/dist/config/oat-config.d.ts.map +1 -1
- package/dist/config/oat-config.js +49 -20
- package/dist/fs/paths.d.ts +12 -0
- package/dist/fs/paths.d.ts.map +1 -1
- package/dist/fs/paths.js +87 -1
- package/package.json +2 -2
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# generate-oat-state.sh - Generate OAT repo state dashboard
|
|
3
|
+
# Usage: ./generate-oat-state.sh
|
|
4
|
+
# Exit codes: 0 = Success, 1 = Error (only for real failures, not missing data)
|
|
5
|
+
|
|
6
|
+
# Use -eu but NOT pipefail - we need graceful degradation for missing data
|
|
7
|
+
set -eu
|
|
8
|
+
|
|
9
|
+
# --- Configuration ---
|
|
10
|
+
DASHBOARD_PATH=".oat/state.md"
|
|
11
|
+
|
|
12
|
+
# --- Error Handling Pattern ---
|
|
13
|
+
# For best-effort parsing, use:
|
|
14
|
+
# result=$(command 2>/dev/null || echo "")
|
|
15
|
+
# result=$(grep ... || true)
|
|
16
|
+
# Never let missing frontmatter or files cause script exit.
|
|
17
|
+
|
|
18
|
+
# --- Functions ---
|
|
19
|
+
|
|
20
|
+
# Resolve PROJECTS_ROOT from env, file, or default
|
|
21
|
+
resolve_projects_root() {
|
|
22
|
+
local root="${OAT_PROJECTS_ROOT:-}"
|
|
23
|
+
if [[ -z "$root" ]] && [[ -f ".oat/projects-root" ]]; then
|
|
24
|
+
root=$(cat ".oat/projects-root" 2>/dev/null || true)
|
|
25
|
+
fi
|
|
26
|
+
root="${root:-.oat/projects/shared}"
|
|
27
|
+
echo "${root%/}" # Strip trailing slash
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
has_any_projects() {
|
|
31
|
+
local projects_root="$1"
|
|
32
|
+
local dir
|
|
33
|
+
[[ -d "$projects_root" ]] || return 1
|
|
34
|
+
for dir in "$projects_root"/*/; do
|
|
35
|
+
[[ -d "$dir" ]] || continue
|
|
36
|
+
return 0
|
|
37
|
+
done
|
|
38
|
+
return 1
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
# Read active project pointer (accepts path or name format)
|
|
42
|
+
# Sets: PROJECT_NAME, PROJECT_PATH, PROJECT_STATUS
|
|
43
|
+
read_active_project() {
|
|
44
|
+
local projects_root="$1"
|
|
45
|
+
local raw_value
|
|
46
|
+
|
|
47
|
+
PROJECT_NAME=""
|
|
48
|
+
PROJECT_PATH=""
|
|
49
|
+
PROJECT_STATUS="not set"
|
|
50
|
+
|
|
51
|
+
if [[ ! -f ".oat/active-project" ]]; then
|
|
52
|
+
return
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
raw_value=$(cat ".oat/active-project" 2>/dev/null || true)
|
|
56
|
+
raw_value=$(echo "$raw_value" | tr -d '[:space:]')
|
|
57
|
+
|
|
58
|
+
if [[ -z "$raw_value" ]]; then
|
|
59
|
+
return
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
# Detect format: path (contains /) or name-only
|
|
63
|
+
if [[ "$raw_value" == */* ]]; then
|
|
64
|
+
PROJECT_NAME=$(basename "$raw_value")
|
|
65
|
+
PROJECT_PATH="$raw_value"
|
|
66
|
+
else
|
|
67
|
+
PROJECT_NAME="$raw_value"
|
|
68
|
+
PROJECT_PATH="${projects_root}/${PROJECT_NAME}"
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
# Validate directory exists
|
|
72
|
+
if [[ ! -d "$PROJECT_PATH" ]]; then
|
|
73
|
+
PROJECT_STATUS="directory missing"
|
|
74
|
+
return
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
# Validate state.md exists
|
|
78
|
+
if [[ ! -f "${PROJECT_PATH}/state.md" ]]; then
|
|
79
|
+
PROJECT_STATUS="state.md missing"
|
|
80
|
+
return
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
PROJECT_STATUS="active"
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
# Parse YAML frontmatter field from file (best-effort, never fails)
|
|
87
|
+
# Usage: parse_frontmatter "file.md" "field_name"
|
|
88
|
+
# Returns: Field value or empty string (never exits on missing data)
|
|
89
|
+
parse_frontmatter() {
|
|
90
|
+
local file="$1"
|
|
91
|
+
local field="$2"
|
|
92
|
+
local content value
|
|
93
|
+
|
|
94
|
+
if [[ ! -f "$file" ]]; then
|
|
95
|
+
echo ""
|
|
96
|
+
return 0
|
|
97
|
+
fi
|
|
98
|
+
|
|
99
|
+
# Extract frontmatter block, then find field - use || true to prevent exit
|
|
100
|
+
content=$(sed -n '/^---$/,/^---$/p' "$file" 2>/dev/null) || true
|
|
101
|
+
if [[ -z "$content" ]]; then
|
|
102
|
+
echo ""
|
|
103
|
+
return 0
|
|
104
|
+
fi
|
|
105
|
+
|
|
106
|
+
# Find field value - grep returns 1 if no match, so use || true
|
|
107
|
+
value=$(echo "$content" | grep "^${field}:" | head -1 | sed "s/^${field}:[[:space:]]*//") || true
|
|
108
|
+
# Strip inline comments used by templates and trim trailing whitespace
|
|
109
|
+
value=$(echo "$value" | sed 's/[[:space:]]#.*$//' | sed 's/[[:space:]]*$//')
|
|
110
|
+
echo "$value"
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
# Read project state from state.md frontmatter
|
|
114
|
+
# Sets: OAT_PHASE, OAT_PHASE_STATUS, OAT_CURRENT_TASK, OAT_LIFECYCLE, OAT_BLOCKERS,
|
|
115
|
+
# OAT_HIL_CHECKPOINTS, OAT_HIL_COMPLETED, OAT_HIL_STATUS
|
|
116
|
+
read_project_state() {
|
|
117
|
+
local state_file="${PROJECT_PATH}/state.md"
|
|
118
|
+
|
|
119
|
+
OAT_PHASE=$(parse_frontmatter "$state_file" "oat_phase")
|
|
120
|
+
OAT_PHASE_STATUS=$(parse_frontmatter "$state_file" "oat_phase_status")
|
|
121
|
+
OAT_CURRENT_TASK=$(parse_frontmatter "$state_file" "oat_current_task")
|
|
122
|
+
OAT_LIFECYCLE=$(parse_frontmatter "$state_file" "oat_lifecycle")
|
|
123
|
+
OAT_BLOCKERS=$(parse_frontmatter "$state_file" "oat_blockers")
|
|
124
|
+
OAT_HIL_CHECKPOINTS=$(parse_frontmatter "$state_file" "oat_hil_checkpoints")
|
|
125
|
+
OAT_HIL_COMPLETED=$(parse_frontmatter "$state_file" "oat_hil_completed")
|
|
126
|
+
OAT_WORKFLOW_MODE=$(parse_frontmatter "$state_file" "oat_workflow_mode")
|
|
127
|
+
|
|
128
|
+
# Defaults
|
|
129
|
+
OAT_PHASE="${OAT_PHASE:-unknown}"
|
|
130
|
+
OAT_PHASE_STATUS="${OAT_PHASE_STATUS:-unknown}"
|
|
131
|
+
if [[ -z "${OAT_CURRENT_TASK:-}" ]] || [[ "${OAT_CURRENT_TASK}" == "null" ]]; then
|
|
132
|
+
OAT_CURRENT_TASK="-"
|
|
133
|
+
fi
|
|
134
|
+
OAT_LIFECYCLE="${OAT_LIFECYCLE:-active}"
|
|
135
|
+
OAT_BLOCKERS="${OAT_BLOCKERS:-[]}"
|
|
136
|
+
OAT_HIL_CHECKPOINTS="${OAT_HIL_CHECKPOINTS:-[]}"
|
|
137
|
+
OAT_HIL_COMPLETED="${OAT_HIL_COMPLETED:-[]}"
|
|
138
|
+
OAT_WORKFLOW_MODE="${OAT_WORKFLOW_MODE:-full}"
|
|
139
|
+
|
|
140
|
+
# Human-in-loop status for current phase
|
|
141
|
+
if phase_in_hil_list "$OAT_PHASE" "$OAT_HIL_CHECKPOINTS"; then
|
|
142
|
+
if phase_in_hil_list "$OAT_PHASE" "$OAT_HIL_COMPLETED"; then
|
|
143
|
+
OAT_HIL_STATUS="passed"
|
|
144
|
+
else
|
|
145
|
+
OAT_HIL_STATUS="pending"
|
|
146
|
+
fi
|
|
147
|
+
else
|
|
148
|
+
OAT_HIL_STATUS="n/a"
|
|
149
|
+
fi
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
# Check whether a phase token appears in a serialized YAML array string
|
|
153
|
+
phase_in_hil_list() {
|
|
154
|
+
local phase="$1"
|
|
155
|
+
local list="$2"
|
|
156
|
+
[[ "$list" == *"\"${phase}\""* ]]
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
# Read knowledge index status
|
|
160
|
+
# Sets: KNOWLEDGE_GENERATED_AT, KNOWLEDGE_MERGE_BASE_SHA, KNOWLEDGE_STATUS
|
|
161
|
+
read_knowledge_status() {
|
|
162
|
+
local index_file=".oat/repo/knowledge/project-index.md"
|
|
163
|
+
|
|
164
|
+
KNOWLEDGE_GENERATED_AT=""
|
|
165
|
+
KNOWLEDGE_MERGE_BASE_SHA=""
|
|
166
|
+
KNOWLEDGE_STATUS="not generated"
|
|
167
|
+
|
|
168
|
+
if [[ ! -f "$index_file" ]]; then
|
|
169
|
+
return
|
|
170
|
+
fi
|
|
171
|
+
|
|
172
|
+
KNOWLEDGE_GENERATED_AT=$(parse_frontmatter "$index_file" "oat_generated_at")
|
|
173
|
+
KNOWLEDGE_MERGE_BASE_SHA=$(parse_frontmatter "$index_file" "oat_source_main_merge_base_sha")
|
|
174
|
+
|
|
175
|
+
if [[ -n "$KNOWLEDGE_GENERATED_AT" ]]; then
|
|
176
|
+
KNOWLEDGE_STATUS="generated"
|
|
177
|
+
fi
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
# Calculate knowledge staleness via git diff (best-effort, never fails)
|
|
181
|
+
# Sets: FILES_CHANGED, KNOWLEDGE_AGE_DAYS, STALENESS_STATUS
|
|
182
|
+
calculate_staleness() {
|
|
183
|
+
FILES_CHANGED=0
|
|
184
|
+
KNOWLEDGE_AGE_DAYS=0
|
|
185
|
+
STALENESS_STATUS="fresh"
|
|
186
|
+
|
|
187
|
+
if [[ -z "$KNOWLEDGE_MERGE_BASE_SHA" ]]; then
|
|
188
|
+
STALENESS_STATUS="unknown"
|
|
189
|
+
return 0
|
|
190
|
+
fi
|
|
191
|
+
|
|
192
|
+
# Count files changed since merge base - git diff may fail if SHA is invalid
|
|
193
|
+
local diff_output
|
|
194
|
+
diff_output=$(git diff --name-only "$KNOWLEDGE_MERGE_BASE_SHA" HEAD 2>/dev/null) || true
|
|
195
|
+
if [[ -n "$diff_output" ]]; then
|
|
196
|
+
FILES_CHANGED=$(echo "$diff_output" | wc -l | awk '{print $1}')
|
|
197
|
+
fi
|
|
198
|
+
|
|
199
|
+
# Calculate age in days - handle both macOS and Linux date formats
|
|
200
|
+
if [[ -n "$KNOWLEDGE_GENERATED_AT" ]]; then
|
|
201
|
+
local gen_epoch today_epoch
|
|
202
|
+
# Try macOS format first
|
|
203
|
+
if gen_epoch=$(date -j -f "%Y-%m-%d" "$KNOWLEDGE_GENERATED_AT" "+%s" 2>/dev/null); then
|
|
204
|
+
: # Success on macOS
|
|
205
|
+
# Then try Linux format
|
|
206
|
+
elif gen_epoch=$(date -d "$KNOWLEDGE_GENERATED_AT" "+%s" 2>/dev/null); then
|
|
207
|
+
: # Success on Linux
|
|
208
|
+
else
|
|
209
|
+
# Fallback: cannot parse date
|
|
210
|
+
gen_epoch=0
|
|
211
|
+
fi
|
|
212
|
+
today_epoch=$(date "+%s")
|
|
213
|
+
if [[ "$gen_epoch" -gt 0 ]]; then
|
|
214
|
+
KNOWLEDGE_AGE_DAYS=$(( (today_epoch - gen_epoch) / 86400 ))
|
|
215
|
+
fi
|
|
216
|
+
fi
|
|
217
|
+
|
|
218
|
+
# Determine staleness
|
|
219
|
+
if [[ "$FILES_CHANGED" -gt 20 ]] || [[ "$KNOWLEDGE_AGE_DAYS" -gt 7 ]]; then
|
|
220
|
+
STALENESS_STATUS="stale"
|
|
221
|
+
elif [[ "$FILES_CHANGED" -gt 5 ]] || [[ "$KNOWLEDGE_AGE_DAYS" -gt 3 ]]; then
|
|
222
|
+
STALENESS_STATUS="aging"
|
|
223
|
+
fi
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
# Compute recommended next step based on state
|
|
227
|
+
# Sets: RECOMMENDED_STEP, RECOMMENDED_REASON
|
|
228
|
+
compute_next_step() {
|
|
229
|
+
RECOMMENDED_STEP=""
|
|
230
|
+
RECOMMENDED_REASON=""
|
|
231
|
+
|
|
232
|
+
# No active project
|
|
233
|
+
if [[ "$PROJECT_STATUS" == "not set" ]]; then
|
|
234
|
+
if [[ "${HAS_PROJECTS:-false}" == "true" ]]; then
|
|
235
|
+
RECOMMENDED_STEP="oat-project-open"
|
|
236
|
+
RECOMMENDED_REASON="Select an existing project to continue work"
|
|
237
|
+
else
|
|
238
|
+
RECOMMENDED_STEP="oat-project-new"
|
|
239
|
+
RECOMMENDED_REASON="Create a new project to start work"
|
|
240
|
+
fi
|
|
241
|
+
return
|
|
242
|
+
fi
|
|
243
|
+
|
|
244
|
+
# Project has issues
|
|
245
|
+
if [[ "$PROJECT_STATUS" != "active" ]]; then
|
|
246
|
+
RECOMMENDED_STEP="oat-project-open"
|
|
247
|
+
RECOMMENDED_REASON="Current project has issues: $PROJECT_STATUS"
|
|
248
|
+
return
|
|
249
|
+
fi
|
|
250
|
+
|
|
251
|
+
# Respect configured human-in-the-loop checkpoints before advancing phase
|
|
252
|
+
if [[ "$OAT_PHASE_STATUS" == "complete" ]] &&
|
|
253
|
+
phase_in_hil_list "$OAT_PHASE" "$OAT_HIL_CHECKPOINTS" &&
|
|
254
|
+
! phase_in_hil_list "$OAT_PHASE" "$OAT_HIL_COMPLETED"; then
|
|
255
|
+
case "$OAT_PHASE" in
|
|
256
|
+
"discovery") RECOMMENDED_STEP="oat-project-discover" ;;
|
|
257
|
+
"spec") RECOMMENDED_STEP="oat-project-spec" ;;
|
|
258
|
+
"design") RECOMMENDED_STEP="oat-project-design" ;;
|
|
259
|
+
"plan") RECOMMENDED_STEP="oat-project-plan" ;;
|
|
260
|
+
"implement") RECOMMENDED_STEP="oat-project-implement" ;;
|
|
261
|
+
*) RECOMMENDED_STEP="oat-project-progress" ;;
|
|
262
|
+
esac
|
|
263
|
+
RECOMMENDED_REASON="Complete ${OAT_PHASE} HiL approval before advancing"
|
|
264
|
+
return
|
|
265
|
+
fi
|
|
266
|
+
|
|
267
|
+
# Map phase + status to next skill by workflow mode
|
|
268
|
+
case "${OAT_WORKFLOW_MODE}:${OAT_PHASE}:${OAT_PHASE_STATUS}" in
|
|
269
|
+
# full mode
|
|
270
|
+
"full:discovery:in_progress") RECOMMENDED_STEP="oat-project-discover"; RECOMMENDED_REASON="Continue discovery phase" ;;
|
|
271
|
+
"full:discovery:complete") RECOMMENDED_STEP="oat-project-spec"; RECOMMENDED_REASON="Create specification from discovery" ;;
|
|
272
|
+
"full:spec:in_progress") RECOMMENDED_STEP="oat-project-spec"; RECOMMENDED_REASON="Continue specification phase" ;;
|
|
273
|
+
"full:spec:complete") RECOMMENDED_STEP="oat-project-design"; RECOMMENDED_REASON="Create design from specification" ;;
|
|
274
|
+
"full:design:in_progress") RECOMMENDED_STEP="oat-project-design"; RECOMMENDED_REASON="Continue design phase" ;;
|
|
275
|
+
"full:design:complete") RECOMMENDED_STEP="oat-project-plan"; RECOMMENDED_REASON="Create implementation plan from design" ;;
|
|
276
|
+
|
|
277
|
+
# quick mode
|
|
278
|
+
"quick:discovery:in_progress") RECOMMENDED_STEP="oat-project-discover"; RECOMMENDED_REASON="Continue quick discovery phase" ;;
|
|
279
|
+
"quick:discovery:complete") RECOMMENDED_STEP="oat-project-plan"; RECOMMENDED_REASON="Generate plan directly for quick workflow" ;;
|
|
280
|
+
|
|
281
|
+
# import mode
|
|
282
|
+
"import:plan:in_progress") RECOMMENDED_STEP="oat-project-import-plan"; RECOMMENDED_REASON="Continue import-plan normalization" ;;
|
|
283
|
+
|
|
284
|
+
# shared routing
|
|
285
|
+
*":plan:in_progress") RECOMMENDED_STEP="oat-project-plan"; RECOMMENDED_REASON="Continue planning phase" ;;
|
|
286
|
+
*":plan:complete") RECOMMENDED_STEP="oat-project-implement"; RECOMMENDED_REASON="Start implementation" ;;
|
|
287
|
+
*":implement:in_progress") RECOMMENDED_STEP="oat-project-implement"; RECOMMENDED_REASON="Continue implementation" ;;
|
|
288
|
+
*":implement:complete") RECOMMENDED_STEP="oat-project-pr-final"; RECOMMENDED_REASON="Generate final PR description (final review passed)" ;;
|
|
289
|
+
*) RECOMMENDED_STEP="oat-project-progress"; RECOMMENDED_REASON="Check current progress" ;;
|
|
290
|
+
esac
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
# List available projects with their phases
|
|
294
|
+
# Output: Markdown formatted list
|
|
295
|
+
list_available_projects() {
|
|
296
|
+
local projects_root="$1"
|
|
297
|
+
local project_dir project_name phase
|
|
298
|
+
|
|
299
|
+
if [[ ! -d "$projects_root" ]]; then
|
|
300
|
+
echo "*(No projects directory found)*"
|
|
301
|
+
return
|
|
302
|
+
fi
|
|
303
|
+
|
|
304
|
+
local found=false
|
|
305
|
+
for project_dir in "$projects_root"/*/; do
|
|
306
|
+
[[ -d "$project_dir" ]] || continue
|
|
307
|
+
project_name=$(basename "$project_dir")
|
|
308
|
+
|
|
309
|
+
if [[ -f "${project_dir}state.md" ]]; then
|
|
310
|
+
phase=$(parse_frontmatter "${project_dir}state.md" "oat_phase")
|
|
311
|
+
phase="${phase:-unknown}"
|
|
312
|
+
echo "- **${project_name}** - ${phase}"
|
|
313
|
+
found=true
|
|
314
|
+
fi
|
|
315
|
+
done
|
|
316
|
+
|
|
317
|
+
if [[ "$found" == "false" ]]; then
|
|
318
|
+
echo "*(No projects found)*"
|
|
319
|
+
fi
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
# Generate the complete dashboard markdown
|
|
323
|
+
generate_dashboard() {
|
|
324
|
+
local projects_root="$1"
|
|
325
|
+
local timestamp
|
|
326
|
+
timestamp=$(date -u +"%Y-%m-%d %H:%M:%S UTC")
|
|
327
|
+
|
|
328
|
+
cat > "$DASHBOARD_PATH" << EOF
|
|
329
|
+
---
|
|
330
|
+
oat_generated: true
|
|
331
|
+
oat_generated_at: $(date -u +"%Y-%m-%d")
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
# OAT Repo State Dashboard
|
|
335
|
+
|
|
336
|
+
**Generated:** ${timestamp}
|
|
337
|
+
|
|
338
|
+
## Active Project
|
|
339
|
+
|
|
340
|
+
EOF
|
|
341
|
+
|
|
342
|
+
# Active project section
|
|
343
|
+
if [[ "$PROJECT_STATUS" == "not set" ]]; then
|
|
344
|
+
echo "*(not set)*" >> "$DASHBOARD_PATH"
|
|
345
|
+
else
|
|
346
|
+
echo "**${PROJECT_NAME}** (\`${PROJECT_PATH}\`)" >> "$DASHBOARD_PATH"
|
|
347
|
+
fi
|
|
348
|
+
|
|
349
|
+
echo "" >> "$DASHBOARD_PATH"
|
|
350
|
+
|
|
351
|
+
# Active project summary (thin; details live in project state.md)
|
|
352
|
+
if [[ "$PROJECT_STATUS" == "active" ]]; then
|
|
353
|
+
cat >> "$DASHBOARD_PATH" << EOF
|
|
354
|
+
## Active Project Summary
|
|
355
|
+
|
|
356
|
+
| Field | Value |
|
|
357
|
+
|-------|-------|
|
|
358
|
+
| Mode | ${OAT_WORKFLOW_MODE} |
|
|
359
|
+
| Phase | ${OAT_PHASE} |
|
|
360
|
+
| Status | ${OAT_PHASE_STATUS} |
|
|
361
|
+
| HiL Gate | ${OAT_HIL_STATUS} |
|
|
362
|
+
| Current Task | ${OAT_CURRENT_TASK} |
|
|
363
|
+
|
|
364
|
+
EOF
|
|
365
|
+
echo "Details: \`${PROJECT_PATH}/state.md\`" >> "$DASHBOARD_PATH"
|
|
366
|
+
echo "" >> "$DASHBOARD_PATH"
|
|
367
|
+
elif [[ "$PROJECT_STATUS" != "not set" ]]; then
|
|
368
|
+
echo "**Warning:** ${PROJECT_STATUS}" >> "$DASHBOARD_PATH"
|
|
369
|
+
echo "" >> "$DASHBOARD_PATH"
|
|
370
|
+
fi
|
|
371
|
+
|
|
372
|
+
# Knowledge status section
|
|
373
|
+
cat >> "$DASHBOARD_PATH" << EOF
|
|
374
|
+
## Knowledge Status
|
|
375
|
+
|
|
376
|
+
| Field | Value |
|
|
377
|
+
|-------|-------|
|
|
378
|
+
| Generated | ${KNOWLEDGE_GENERATED_AT:-N/A} |
|
|
379
|
+
| Age | ${KNOWLEDGE_AGE_DAYS} days |
|
|
380
|
+
| Files Changed | ${FILES_CHANGED} |
|
|
381
|
+
| Status | ${STALENESS_STATUS} |
|
|
382
|
+
|
|
383
|
+
EOF
|
|
384
|
+
|
|
385
|
+
# Recommended next step
|
|
386
|
+
cat >> "$DASHBOARD_PATH" << EOF
|
|
387
|
+
## Recommended Next Step
|
|
388
|
+
|
|
389
|
+
**${RECOMMENDED_STEP}** - ${RECOMMENDED_REASON}
|
|
390
|
+
|
|
391
|
+
## Quick Commands
|
|
392
|
+
|
|
393
|
+
- \`oat-project-progress\` - Check current status
|
|
394
|
+
- \`oat-repo-knowledge-index\` - Refresh knowledge base
|
|
395
|
+
- \`oat-project-new\` - Create a full-lifecycle project
|
|
396
|
+
- \`oat-project-quick-start\` - Create a quick workflow project
|
|
397
|
+
- \`oat-project-import-plan\` - Import an external provider plan
|
|
398
|
+
- \`oat-project-open\` - Switch active project
|
|
399
|
+
- \`oat-project-clear-active\` - Clear active project
|
|
400
|
+
- \`oat-project-complete\` - Mark project complete
|
|
401
|
+
|
|
402
|
+
## Available Projects
|
|
403
|
+
|
|
404
|
+
EOF
|
|
405
|
+
|
|
406
|
+
list_available_projects "$projects_root" >> "$DASHBOARD_PATH"
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
# --- Main ---
|
|
410
|
+
main() {
|
|
411
|
+
# Validate we're in a git repo
|
|
412
|
+
if ! git rev-parse --git-dir > /dev/null 2>&1; then
|
|
413
|
+
echo "Error: Must be run from a git repository" >&2
|
|
414
|
+
exit 1
|
|
415
|
+
fi
|
|
416
|
+
|
|
417
|
+
local projects_root
|
|
418
|
+
projects_root=$(resolve_projects_root)
|
|
419
|
+
|
|
420
|
+
if has_any_projects "$projects_root"; then
|
|
421
|
+
HAS_PROJECTS="true"
|
|
422
|
+
else
|
|
423
|
+
HAS_PROJECTS="false"
|
|
424
|
+
fi
|
|
425
|
+
|
|
426
|
+
read_active_project "$projects_root"
|
|
427
|
+
|
|
428
|
+
if [[ "$PROJECT_STATUS" == "active" ]]; then
|
|
429
|
+
read_project_state
|
|
430
|
+
fi
|
|
431
|
+
|
|
432
|
+
read_knowledge_status
|
|
433
|
+
calculate_staleness
|
|
434
|
+
compute_next_step
|
|
435
|
+
|
|
436
|
+
generate_dashboard "$projects_root"
|
|
437
|
+
|
|
438
|
+
echo "Dashboard generated: $DASHBOARD_PATH"
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
main "$@"
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# generate-thin-index.sh - Generate thin project-index.md for quick orientation
|
|
3
|
+
#
|
|
4
|
+
# Usage: ./generate-thin-index.sh [HEAD_SHA] [MERGE_BASE_SHA]
|
|
5
|
+
#
|
|
6
|
+
# If SHAs not provided, computes them from current git state.
|
|
7
|
+
# Output: Writes .oat/repo/knowledge/project-index.md
|
|
8
|
+
|
|
9
|
+
set -euo pipefail
|
|
10
|
+
|
|
11
|
+
# Get SHAs from args or compute
|
|
12
|
+
HEAD_SHA="${1:-$(git rev-parse HEAD 2>/dev/null || echo "unknown")}"
|
|
13
|
+
MERGE_BASE_SHA="${2:-$(git merge-base HEAD origin/main 2>/dev/null || git rev-parse HEAD 2>/dev/null || echo "unknown")}"
|
|
14
|
+
|
|
15
|
+
# Current date (portable)
|
|
16
|
+
DATE=$(date +%F)
|
|
17
|
+
|
|
18
|
+
# Get repo name from package.json or directory (supports node, jq, or grep fallback)
|
|
19
|
+
REPO_NAME=""
|
|
20
|
+
if [ -f package.json ]; then
|
|
21
|
+
# Try node first
|
|
22
|
+
if command -v node >/dev/null 2>&1; then
|
|
23
|
+
REPO_NAME=$(node -pe "try{require('./package.json').name||''}catch(e){''}" 2>/dev/null)
|
|
24
|
+
# Try jq second
|
|
25
|
+
elif command -v jq >/dev/null 2>&1; then
|
|
26
|
+
REPO_NAME=$(jq -r '.name // ""' package.json 2>/dev/null)
|
|
27
|
+
# Fallback to grep
|
|
28
|
+
else
|
|
29
|
+
REPO_NAME=$(grep -m1 '"name"' package.json 2>/dev/null | sed 's/.*"name"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/')
|
|
30
|
+
fi
|
|
31
|
+
fi
|
|
32
|
+
if [ -z "$REPO_NAME" ]; then
|
|
33
|
+
REPO_NAME=$(basename "$(pwd)")
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
# Quick directory tree (2 levels, exclude common noise)
|
|
37
|
+
TREE=$(find . -maxdepth 2 -mindepth 1 \
|
|
38
|
+
-not -path '*/.git/*' \
|
|
39
|
+
-not -path '*/node_modules/*' \
|
|
40
|
+
-not -path '*/dist/*' \
|
|
41
|
+
-not -path '*/build/*' \
|
|
42
|
+
-not -path '*/.next/*' \
|
|
43
|
+
-not -path '*/.turbo/*' \
|
|
44
|
+
-not -path '*/coverage/*' \
|
|
45
|
+
-print 2>/dev/null | sed 's#^\./##' | sort | head -200)
|
|
46
|
+
|
|
47
|
+
# Detect package manager
|
|
48
|
+
PKG_MANAGER="unknown"
|
|
49
|
+
[ -f pnpm-lock.yaml ] && PKG_MANAGER="pnpm"
|
|
50
|
+
[ -f yarn.lock ] && PKG_MANAGER="yarn"
|
|
51
|
+
[ -f package-lock.json ] && PKG_MANAGER="npm"
|
|
52
|
+
[ -f Pipfile.lock ] && PKG_MANAGER="pipenv"
|
|
53
|
+
[ -f poetry.lock ] && PKG_MANAGER="poetry"
|
|
54
|
+
[ -f Cargo.lock ] && PKG_MANAGER="cargo"
|
|
55
|
+
[ -f go.mod ] && PKG_MANAGER="go"
|
|
56
|
+
|
|
57
|
+
# Extract scripts from package.json if Node project (supports node, jq, or grep fallback)
|
|
58
|
+
SCRIPTS=""
|
|
59
|
+
if [ -f package.json ]; then
|
|
60
|
+
if command -v node >/dev/null 2>&1; then
|
|
61
|
+
SCRIPTS=$(node -pe "try{Object.keys(require('./package.json').scripts||{}).join(', ')}catch(e){''}" 2>/dev/null || echo "")
|
|
62
|
+
elif command -v jq >/dev/null 2>&1; then
|
|
63
|
+
SCRIPTS=$(jq -r '.scripts // {} | keys | join(", ")' package.json 2>/dev/null || echo "")
|
|
64
|
+
else
|
|
65
|
+
# Fallback: extract script names with grep (crude but works for most cases)
|
|
66
|
+
SCRIPTS=$(grep -E '^\s+"[a-zA-Z0-9:_-]+"\s*:' package.json 2>/dev/null | \
|
|
67
|
+
sed -n '/"scripts"/,/^[[:space:]]*}/p' | \
|
|
68
|
+
grep -E '^\s+"[a-zA-Z0-9:_-]+"\s*:' | \
|
|
69
|
+
sed 's/.*"\([^"]*\)".*/\1/' | \
|
|
70
|
+
tr '\n' ', ' | sed 's/, $//')
|
|
71
|
+
fi
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
# Find entry points (cheap heuristics)
|
|
75
|
+
ENTRYPOINTS=$(find . -maxdepth 4 -type f \
|
|
76
|
+
\( -name 'index.*' -o -name 'main.*' -o -name 'app.*' -o -name 'server.*' -o -name 'cli.*' \) \
|
|
77
|
+
-not -path '*/node_modules/*' \
|
|
78
|
+
-not -path '*/.git/*' \
|
|
79
|
+
-not -path '*/dist/*' \
|
|
80
|
+
-not -path '*/build/*' \
|
|
81
|
+
-print 2>/dev/null | sed 's#^\./##' | sort | head -50)
|
|
82
|
+
|
|
83
|
+
# Detect key config files (portable - check each individually)
|
|
84
|
+
CONFIGS=""
|
|
85
|
+
for cfg in package.json pnpm-lock.yaml yarn.lock package-lock.json \
|
|
86
|
+
tsconfig.json biome.json eslint.config.js eslint.config.mjs .eslintrc.js .eslintrc.json \
|
|
87
|
+
vitest.config.ts vitest.config.js jest.config.ts jest.config.js pytest.ini pyproject.toml \
|
|
88
|
+
go.mod Cargo.toml Makefile; do
|
|
89
|
+
[ -f "$cfg" ] && CONFIGS="$CONFIGS $cfg"
|
|
90
|
+
done
|
|
91
|
+
CONFIGS=$(echo "$CONFIGS" | xargs) # trim whitespace
|
|
92
|
+
|
|
93
|
+
# Extract test command from scripts (supports node, jq, or grep fallback)
|
|
94
|
+
TEST_CMD=""
|
|
95
|
+
if [ -f package.json ]; then
|
|
96
|
+
if command -v node >/dev/null 2>&1; then
|
|
97
|
+
TEST_CMD=$(node -pe "try{require('./package.json').scripts?.test||''}catch(e){''}" 2>/dev/null || echo "")
|
|
98
|
+
elif command -v jq >/dev/null 2>&1; then
|
|
99
|
+
TEST_CMD=$(jq -r '.scripts.test // ""' package.json 2>/dev/null || echo "")
|
|
100
|
+
else
|
|
101
|
+
# Fallback: look for test script with grep
|
|
102
|
+
TEST_CMD=$(grep -A1 '"test"' package.json 2>/dev/null | grep -v '"test"' | head -1 | sed 's/.*"test"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/' | tr -d ',')
|
|
103
|
+
fi
|
|
104
|
+
fi
|
|
105
|
+
if [ -z "$TEST_CMD" ] && [ -f Makefile ]; then
|
|
106
|
+
grep -q "^test:" Makefile 2>/dev/null && TEST_CMD="make test"
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
# Format testing section
|
|
110
|
+
if [ -n "$TEST_CMD" ]; then
|
|
111
|
+
TESTING_SECTION="**Test Command:** \`${TEST_CMD}\`"
|
|
112
|
+
else
|
|
113
|
+
TESTING_SECTION="*Test command will be documented after analysis.*"
|
|
114
|
+
fi
|
|
115
|
+
|
|
116
|
+
# Format entry points as list
|
|
117
|
+
ENTRYPOINTS_LIST=""
|
|
118
|
+
if [ -n "$ENTRYPOINTS" ]; then
|
|
119
|
+
ENTRYPOINTS_LIST=$(echo "$ENTRYPOINTS" | while read -r ep; do echo "- \`$ep\`"; done)
|
|
120
|
+
else
|
|
121
|
+
ENTRYPOINTS_LIST="- None detected"
|
|
122
|
+
fi
|
|
123
|
+
|
|
124
|
+
# Format tree as markdown code block content
|
|
125
|
+
TREE_FORMATTED=$(echo "$TREE" | sed 's/^/ /')
|
|
126
|
+
|
|
127
|
+
# Format configs as list
|
|
128
|
+
CONFIGS_LIST=""
|
|
129
|
+
if [ -n "$CONFIGS" ]; then
|
|
130
|
+
for cfg in $CONFIGS; do
|
|
131
|
+
CONFIGS_LIST="$CONFIGS_LIST
|
|
132
|
+
- \`$cfg\`"
|
|
133
|
+
done
|
|
134
|
+
else
|
|
135
|
+
CONFIGS_LIST="
|
|
136
|
+
- None detected"
|
|
137
|
+
fi
|
|
138
|
+
|
|
139
|
+
# Ensure output directory exists
|
|
140
|
+
mkdir -p .oat/repo/knowledge
|
|
141
|
+
|
|
142
|
+
# Write the thin index
|
|
143
|
+
cat > .oat/repo/knowledge/project-index.md <<EOF
|
|
144
|
+
---
|
|
145
|
+
oat_generated: true
|
|
146
|
+
oat_generated_at: ${DATE}
|
|
147
|
+
oat_source_head_sha: ${HEAD_SHA}
|
|
148
|
+
oat_source_main_merge_base_sha: ${MERGE_BASE_SHA}
|
|
149
|
+
oat_index_type: thin
|
|
150
|
+
oat_warning: "GENERATED FILE - Thin index, will be enriched after mapper completion"
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
# ${REPO_NAME}
|
|
154
|
+
|
|
155
|
+
## Overview
|
|
156
|
+
|
|
157
|
+
*Overview will be enriched after codebase analysis completes.*
|
|
158
|
+
|
|
159
|
+
## Quick Orientation
|
|
160
|
+
|
|
161
|
+
**Package Manager:** ${PKG_MANAGER}
|
|
162
|
+
|
|
163
|
+
**Key Scripts:** ${SCRIPTS:-None detected}
|
|
164
|
+
|
|
165
|
+
**Entry Points:**
|
|
166
|
+
${ENTRYPOINTS_LIST}
|
|
167
|
+
|
|
168
|
+
## Project Structure (Top-Level)
|
|
169
|
+
|
|
170
|
+
\`\`\`
|
|
171
|
+
${TREE_FORMATTED}
|
|
172
|
+
\`\`\`
|
|
173
|
+
|
|
174
|
+
## Configuration Files
|
|
175
|
+
${CONFIGS_LIST}
|
|
176
|
+
|
|
177
|
+
## Testing
|
|
178
|
+
|
|
179
|
+
${TESTING_SECTION}
|
|
180
|
+
|
|
181
|
+
## Next Steps
|
|
182
|
+
|
|
183
|
+
This is a thin index generated for quick orientation. Full details will be available after codebase analysis completes in:
|
|
184
|
+
|
|
185
|
+
- [stack.md](stack.md) - Technologies and dependencies (pending)
|
|
186
|
+
- [architecture.md](architecture.md) - System design and patterns (pending)
|
|
187
|
+
- [structure.md](structure.md) - Directory layout (pending)
|
|
188
|
+
- [integrations.md](integrations.md) - External services (pending)
|
|
189
|
+
- [testing.md](testing.md) - Test structure and practices (pending)
|
|
190
|
+
- [conventions.md](conventions.md) - Code style and patterns (pending)
|
|
191
|
+
- [concerns.md](concerns.md) - Technical debt and issues (pending)
|
|
192
|
+
EOF
|
|
193
|
+
|
|
194
|
+
# Count non-empty lines for accurate entrypoint count
|
|
195
|
+
ENTRYPOINT_COUNT=$(printf "%s\n" "$ENTRYPOINTS" | sed '/^$/d' | wc -l | tr -d ' ')
|
|
196
|
+
|
|
197
|
+
echo "Generated .oat/repo/knowledge/project-index.md (thin index)"
|
|
198
|
+
echo " Repo: ${REPO_NAME}"
|
|
199
|
+
echo " Package Manager: ${PKG_MANAGER}"
|
|
200
|
+
echo " Entry Points: ${ENTRYPOINT_COUNT} detected"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: oat-agent-instructions-analyze
|
|
3
|
-
version: 1.
|
|
3
|
+
version: 1.12.0
|
|
4
4
|
description: Run when you need to evaluate agent instruction file coverage, quality, and drift. Produces a severity-rated analysis artifact. Run before oat-agent-instructions-apply to identify what needs improvement.
|
|
5
5
|
disable-model-invocation: true
|
|
6
6
|
user-invocable: true
|
|
@@ -78,8 +78,10 @@ or fill in missing evidence gaps on its own.
|
|
|
78
78
|
**Resolve providers:**
|
|
79
79
|
|
|
80
80
|
```bash
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
# Set SKILL_DIR to the absolute directory containing this loaded SKILL.md.
|
|
82
|
+
SCRIPT_DIR="$SKILL_DIR/scripts"
|
|
83
|
+
SCOPE_ROOT="$(cd "$SKILL_DIR/../../.." && pwd)"
|
|
84
|
+
TRACKING_SCRIPT="$SCOPE_ROOT/.oat/scripts/resolve-tracking.sh"
|
|
83
85
|
PROVIDERS=$(bash "$SCRIPT_DIR/resolve-providers.sh" --non-interactive)
|
|
84
86
|
# Or with explicit override:
|
|
85
87
|
# PROVIDERS=$(bash "$SCRIPT_DIR/resolve-providers.sh" --providers claude,cursor)
|
|
@@ -468,7 +470,9 @@ If the loop is disabled, note `Auto artifact review: skipped (workflow.autoArtif
|
|
|
468
470
|
**Update tracking:**
|
|
469
471
|
|
|
470
472
|
```bash
|
|
471
|
-
|
|
473
|
+
# Set SKILL_DIR to the absolute directory containing this loaded SKILL.md.
|
|
474
|
+
SCOPE_ROOT="$(cd "$SKILL_DIR/../../.." && pwd)"
|
|
475
|
+
TRACKING_SCRIPT="$SCOPE_ROOT/.oat/scripts/resolve-tracking.sh"
|
|
472
476
|
ROOT_TARGET=$(bash "$TRACKING_SCRIPT" root)
|
|
473
477
|
ROOT_HASH=$(echo "$ROOT_TARGET" | jq -r '.commitHash')
|
|
474
478
|
ROOT_BRANCH=$(echo "$ROOT_TARGET" | jq -r '.baseBranch')
|
|
@@ -526,6 +530,7 @@ Next step: Run oat-agent-instructions-apply to act on these findings.
|
|
|
526
530
|
- Bundle summary template: `references/bundle-summary-template.md`
|
|
527
531
|
- Bundle manifest template: `references/recommendations-manifest-template.yaml`
|
|
528
532
|
- Recommendation pack template: `references/recommendation-pack-template.md`
|
|
529
|
-
- Tracking script:
|
|
533
|
+
- Tracking script: `$SCOPE_ROOT/.oat/scripts/resolve-tracking.sh`, where
|
|
534
|
+
`SCOPE_ROOT` is derived from this loaded skill's directory.
|
|
530
535
|
- Provider resolution: `scripts/resolve-providers.sh`
|
|
531
536
|
- File discovery: `scripts/resolve-instruction-files.sh`
|