@indigoai-us/hq-cli 5.345.117 → 5.345.119
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/CHANGELOG.md +18 -0
- package/assets/scaffold/core/scripts/pipeline-conductor.sh +2671 -0
- package/assets/scaffold/core/scripts/pipeline-driver.sh +820 -0
- package/assets/scaffold/core/scripts/pipeline-envelope.sh +211 -0
- package/dist/command-catalog.generated.d.ts +34 -0
- package/dist/command-catalog.generated.js +40 -0
- package/dist/commands/core-checkpoint-native.d.ts +17 -3
- package/dist/commands/core-checkpoint-native.js +48 -8
- package/dist/commands/core-derive-trigger-facts-native.js +15 -7
- package/dist/commands/core-migrate-policy-triggers-native.js +3 -1
- package/dist/commands/core-pipeline-conductor-command.d.ts +5 -0
- package/dist/commands/core-pipeline-conductor-command.js +138 -0
- package/dist/commands/core-pipeline-conductor-native.d.ts +7 -0
- package/dist/commands/core-pipeline-conductor-native.js +2950 -0
- package/dist/commands/core-pipeline-driver-native.d.ts +24 -0
- package/dist/commands/core-pipeline-driver-native.js +843 -0
- package/dist/commands/core-pipeline-driver-process.d.ts +4 -0
- package/dist/commands/core-pipeline-driver-process.js +68 -0
- package/dist/commands/core-pipeline-envelope-native.d.ts +4 -0
- package/dist/commands/core-pipeline-envelope-native.js +87 -0
- package/dist/commands/core-policy.js +3 -0
- package/dist/commands/core-worker-lint-native.d.ts +0 -1
- package/dist/commands/core-worker-lint-native.js +0 -1
- package/dist/commands/core-worker-share-native.js +2 -2
- package/dist/commands/core-worker-skills-command.d.ts +1 -1
- package/dist/commands/core-worker-skills-command.js +3 -20
- package/dist/commands/core.d.ts +5 -1
- package/dist/commands/core.js +8 -9
- package/dist/commands/integrations-core.d.ts +7 -1
- package/dist/commands/integrations-core.js +17 -4
- package/dist/commands/integrations.js +91 -22
- package/dist/commands/storage-gate.d.ts +4 -3
- package/dist/commands/storage-gate.js +4 -3
- package/dist/fast-scaffold.js +0 -2
- package/dist/lib/storage-feature-flag.d.ts +7 -7
- package/package.json +1 -1
- package/assets/scaffold/core/scripts/lint-shared-worker-skills.sh +0 -197
- package/assets/scaffold/core/scripts/share-worker-skill.sh +0 -178
- package/dist/commands/core-native-worker-skills-flag.d.ts +0 -4
- package/dist/commands/core-native-worker-skills-flag.js +0 -7
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# lint-shared-worker-skills.sh — fail if a worker-scoped skill is duplicated by
|
|
3
|
-
# copy instead of being single-sourced through the shared-skills convention.
|
|
4
|
-
#
|
|
5
|
-
# THE DRIFT PROBLEM this guards against: a skill used by several workers used to
|
|
6
|
-
# be physically COPIED into each worker's skills/ directory. Editing one copy
|
|
7
|
-
# left the others stale, so the copies drifted apart over time (e.g. a shared
|
|
8
|
-
# e2e-testing skill splitting into two divergent versions). The fix is to keep
|
|
9
|
-
# ONE canonical file under a scope-appropriate `_shared-skills/` store and point
|
|
10
|
-
# each sharing worker's skill entry at it with a relative symlink — see
|
|
11
|
-
# core/knowledge/public/hq-core/shared-worker-skills.md.
|
|
12
|
-
#
|
|
13
|
-
# This linter makes that convention enforceable. It flags two failure shapes:
|
|
14
|
-
#
|
|
15
|
-
# DUPLICATE — two or more NON-symlink skill files, WITHIN A SINGLE OWNERSHIP
|
|
16
|
-
# DOMAIN, whose byte content is identical. Identical bytes across
|
|
17
|
-
# two real files in the same domain is exactly an un-single-sourced
|
|
18
|
-
# copy: the moment someone edits one, they drift. (Symlinks that
|
|
19
|
-
# resolve to a shared canonical are single-sourced and are NOT
|
|
20
|
-
# flagged, even though their resolved content matches.)
|
|
21
|
-
# BROKEN — a skill entry that is a symlink whose target does not resolve.
|
|
22
|
-
#
|
|
23
|
-
# It deliberately does NOT flag two same-NAMED skills whose content differs
|
|
24
|
-
# (e.g. an API-level vs a browser-level e2e skill): distinct content means they
|
|
25
|
-
# are distinct skills that merely share a filename, not a drifted share.
|
|
26
|
-
#
|
|
27
|
-
# OWNERSHIP DOMAINS — filesystem adjacency does NOT establish duplicate
|
|
28
|
-
# ownership, so comparison is partitioned by the tree that OWNS a skill (policy
|
|
29
|
-
# hq-lint-comparison-domains-must-match-ownership):
|
|
30
|
-
#
|
|
31
|
-
# - `core/workers` — the curated first-party worker library
|
|
32
|
-
# - `core/packages/<pack>` — one installed pack (self-contained; may legally
|
|
33
|
-
# vendor a byte-identical copy of a core worker)
|
|
34
|
-
# - `companies/<co>` — one tenant's workers
|
|
35
|
-
#
|
|
36
|
-
# A byte-identical file in TWO DIFFERENT domains (a pack vendoring a core skill,
|
|
37
|
-
# or two packs shipping the same skill) is intentional distribution, NOT drift,
|
|
38
|
-
# and is never flagged. Excluded from the scan entirely: dot-directories
|
|
39
|
-
# (`.archive/`, `.git/`, …) and `._*` AppleDouble OS-metadata files — byte-
|
|
40
|
-
# identical by design, and not skills.
|
|
41
|
-
#
|
|
42
|
-
# Usage: lint-shared-worker-skills.sh [root ...]
|
|
43
|
-
# Default roots: core/workers core/packages (the SHIPPED hq-core scope —
|
|
44
|
-
# company workers live under companies/<co>/ and are linted per-tenant; pass
|
|
45
|
-
# them explicitly to include them).
|
|
46
|
-
#
|
|
47
|
-
# Exit 0 + "OK:" line when clean; exit 1 + a report naming every offending group
|
|
48
|
-
# when not. Matches the loud-and-specific style of lint-skill-script-refs.sh.
|
|
49
|
-
|
|
50
|
-
set -euo pipefail
|
|
51
|
-
|
|
52
|
-
if [[ ${1-} == "--help" || ${1-} == "-h" ]]; then
|
|
53
|
-
printf '%s\n' \
|
|
54
|
-
'Usage: lint-shared-worker-skills.sh [root ...]' \
|
|
55
|
-
'Default roots: core/workers core/packages'
|
|
56
|
-
exit 0
|
|
57
|
-
fi
|
|
58
|
-
|
|
59
|
-
repo_root="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
|
|
60
|
-
cd "$repo_root"
|
|
61
|
-
|
|
62
|
-
roots=("$@")
|
|
63
|
-
if [[ ${#roots[@]} -gt 0 ]]; then
|
|
64
|
-
for root in "${roots[@]}"; do
|
|
65
|
-
if [[ ! -d "$root" ]]; then
|
|
66
|
-
printf 'lint-shared-worker-skills: root is not a directory: %s\n' "$root" >&2
|
|
67
|
-
exit 2
|
|
68
|
-
fi
|
|
69
|
-
done
|
|
70
|
-
fi
|
|
71
|
-
|
|
72
|
-
if [[ ${#roots[@]} -eq 0 ]]; then
|
|
73
|
-
roots=(core/workers core/packages)
|
|
74
|
-
fi
|
|
75
|
-
|
|
76
|
-
# Content hash of a file, portable across Linux and macOS (neither guaranteed to
|
|
77
|
-
# ship the other's tool): md5sum (GNU) → md5 (BSD/macOS) → shasum (Perl, both).
|
|
78
|
-
content_hash() {
|
|
79
|
-
if command -v md5sum >/dev/null 2>&1; then
|
|
80
|
-
md5sum "$1" | cut -d' ' -f1
|
|
81
|
-
elif command -v md5 >/dev/null 2>&1; then
|
|
82
|
-
md5 -q "$1"
|
|
83
|
-
else
|
|
84
|
-
shasum "$1" | cut -d' ' -f1
|
|
85
|
-
fi
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
# The ownership domain that OWNS a skill path — the boundary within which two
|
|
89
|
-
# byte-identical files are a real duplicate. Across domains, identical content
|
|
90
|
-
# is intentional (a pack vendoring a core skill, two packs shipping the same
|
|
91
|
-
# skill), so it must never be compared. See policy header above.
|
|
92
|
-
domain_of() {
|
|
93
|
-
local p="${1#./}" rest
|
|
94
|
-
case "$p" in
|
|
95
|
-
core/packages/*) rest="${p#core/packages/}"; printf 'core/packages/%s' "${rest%%/*}" ;;
|
|
96
|
-
companies/*) rest="${p#companies/}"; printf 'companies/%s' "${rest%%/*}" ;;
|
|
97
|
-
core/workers/*|core/workers) printf 'core/workers' ;;
|
|
98
|
-
# Arbitrary root (custom scans, tests): the top path segment is the domain.
|
|
99
|
-
*) printf '%s' "${p%%/*}" ;;
|
|
100
|
-
esac
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
# Collect skill entries: regular files AND symlinks named *.md under any
|
|
104
|
-
# .../skills/... path. -type l must be matched explicitly — a symlink is not a
|
|
105
|
-
# -type f, so a skills symlink would otherwise be invisible to the scan.
|
|
106
|
-
# EXCLUDED: any dot-directory component (`*/.*/*` — covers `.archive/`, `.git/`)
|
|
107
|
-
# and `._*` AppleDouble files; both are byte-identical by design and not skills.
|
|
108
|
-
mapfile -t entries < <(
|
|
109
|
-
find "${roots[@]}" \( -type f -o -type l \) -path '*/skills/*.md' \
|
|
110
|
-
-not -path '*/.*/*' -not -name '._*' 2>/dev/null | sort
|
|
111
|
-
)
|
|
112
|
-
|
|
113
|
-
# Empty is clean — and guards `"${entries[@]}"` under `set -u` on bash 3.2
|
|
114
|
-
# (macOS), which errors on an empty array expansion.
|
|
115
|
-
if [[ ${#entries[@]} -eq 0 ]]; then
|
|
116
|
-
echo "OK: worker-scoped skills are single-sourced (0 skill entries under: ${roots[*]})"
|
|
117
|
-
exit 0
|
|
118
|
-
fi
|
|
119
|
-
|
|
120
|
-
broken=()
|
|
121
|
-
# Parallel arrays keyed by "<domain>|<content-hash>": hash_keys[i] is that
|
|
122
|
-
# composite key, hash_regfiles[i] a newline-joined list of the NON-symlink files
|
|
123
|
-
# carrying it. Keying on domain AS WELL AS hash is what confines a duplicate
|
|
124
|
-
# finding to a single ownership tree — two identical files in different domains
|
|
125
|
-
# land in different buckets and are never flagged. Bash 3.2 (macOS) has no
|
|
126
|
-
# portable associative arrays, so a linear scan over parallel arrays keeps this
|
|
127
|
-
# runnable everywhere HQ runs.
|
|
128
|
-
hash_keys=()
|
|
129
|
-
hash_regfiles=()
|
|
130
|
-
|
|
131
|
-
hash_index() { # echo the index of $1 in hash_keys, or -1
|
|
132
|
-
local want="$1" i
|
|
133
|
-
for i in "${!hash_keys[@]}"; do
|
|
134
|
-
if [[ "${hash_keys[$i]}" == "$want" ]]; then
|
|
135
|
-
echo "$i"; return 0
|
|
136
|
-
fi
|
|
137
|
-
done
|
|
138
|
-
echo "-1"
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
for entry in "${entries[@]}"; do
|
|
142
|
-
if [[ -L "$entry" ]]; then
|
|
143
|
-
# Symlink: single-sourced by design. Only a DANGLING one is a problem.
|
|
144
|
-
if [[ ! -e "$entry" ]]; then
|
|
145
|
-
broken+=("$entry")
|
|
146
|
-
fi
|
|
147
|
-
continue
|
|
148
|
-
fi
|
|
149
|
-
# Regular file: bucket it by (ownership domain, byte content). Two regular
|
|
150
|
-
# files sharing a bucket are two copies of the same skill in the same tree —
|
|
151
|
-
# the drift hazard.
|
|
152
|
-
key="$(domain_of "$entry")|$(content_hash "$entry")"
|
|
153
|
-
idx="$(hash_index "$key")"
|
|
154
|
-
if [[ "$idx" == "-1" ]]; then
|
|
155
|
-
hash_keys+=("$key")
|
|
156
|
-
hash_regfiles+=("$entry")
|
|
157
|
-
else
|
|
158
|
-
hash_regfiles[$idx]="${hash_regfiles[$idx]}"$'\n'"$entry"
|
|
159
|
-
fi
|
|
160
|
-
done
|
|
161
|
-
|
|
162
|
-
findings=0
|
|
163
|
-
|
|
164
|
-
for i in "${!hash_keys[@]}"; do
|
|
165
|
-
group="${hash_regfiles[$i]}"
|
|
166
|
-
count="$(printf '%s\n' "$group" | grep -c .)"
|
|
167
|
-
if [[ "$count" -ge 2 ]]; then
|
|
168
|
-
if [[ $findings -eq 0 ]]; then
|
|
169
|
-
echo "lint-shared-worker-skills: FAIL — duplicated worker skills (single-source these via _shared-skills/ + relative symlinks):" >&2
|
|
170
|
-
fi
|
|
171
|
-
findings=$((findings + 1))
|
|
172
|
-
domain="${hash_keys[$i]%%|*}"
|
|
173
|
-
echo " DUPLICATE in domain '${domain}' (identical content, ${count} copies — pick one canonical and symlink the rest):" >&2
|
|
174
|
-
printf ' %s\n' "$group" >&2
|
|
175
|
-
fi
|
|
176
|
-
done
|
|
177
|
-
|
|
178
|
-
if [[ ${#broken[@]} -gt 0 ]]; then
|
|
179
|
-
if [[ $findings -eq 0 ]]; then
|
|
180
|
-
echo "lint-shared-worker-skills: FAIL — broken shared-skill symlink(s):" >&2
|
|
181
|
-
fi
|
|
182
|
-
findings=$((findings + ${#broken[@]}))
|
|
183
|
-
echo " BROKEN (symlink target does not resolve):" >&2
|
|
184
|
-
printf ' %s\n' "${broken[@]}" >&2
|
|
185
|
-
fi
|
|
186
|
-
|
|
187
|
-
if [[ $findings -gt 0 ]]; then
|
|
188
|
-
echo "" >&2
|
|
189
|
-
echo " Fix: keep ONE canonical file in the narrowest-scope _shared-skills/ store" >&2
|
|
190
|
-
echo " (core/workers/_shared-skills, core/packages/<pack>/workers/_shared-skills," >&2
|
|
191
|
-
echo " or companies/<co>/workers/_shared-skills) and replace each duplicate with a" >&2
|
|
192
|
-
echo " relative symlink. Helper: hq core worker share" >&2
|
|
193
|
-
echo " Doc: core/knowledge/public/hq-core/shared-worker-skills.md" >&2
|
|
194
|
-
exit 1
|
|
195
|
-
fi
|
|
196
|
-
|
|
197
|
-
echo "OK: worker-scoped skills are single-sourced (${#entries[@]} skill entries scanned under: ${roots[*]})"
|
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# share-worker-skill.sh — convert duplicated worker-scoped skill copies into a
|
|
3
|
-
# single canonical file plus relative symlinks, the migration step for the
|
|
4
|
-
# shared-worker-skills convention (core/knowledge/public/hq-core/shared-worker-skills.md).
|
|
5
|
-
#
|
|
6
|
-
# This performs the ONLY mechanical move the design needs: it never edits any
|
|
7
|
-
# worker.yaml (the skill name still resolves to the same path — only the file
|
|
8
|
-
# type changes from regular file to symlink), and it never touches a skill
|
|
9
|
-
# resolver. `/run` reads {worker}/skills/{skill}.md and follows the symlink
|
|
10
|
-
# transparently, so the change is purely file-layout.
|
|
11
|
-
#
|
|
12
|
-
# Usage:
|
|
13
|
-
# share-worker-skill.sh <scope-dir> <skill-name> <worker-skill-path> [<worker-skill-path> ...]
|
|
14
|
-
#
|
|
15
|
-
# <scope-dir> The narrowest scope that contains EVERY sharing worker,
|
|
16
|
-
# e.g. core/workers, core/packages/<pack>/workers, or
|
|
17
|
-
# companies/<co>/workers. The canonical file is created at
|
|
18
|
-
# <scope-dir>/_shared-skills/<skill-name>.md.
|
|
19
|
-
# <skill-name> Bare skill name (no .md), e.g. e2e-testing.
|
|
20
|
-
# <worker-skill-path> Each worker's current copy, e.g.
|
|
21
|
-
# core/workers/foo/skills/e2e-testing.md
|
|
22
|
-
#
|
|
23
|
-
# Safety rails:
|
|
24
|
-
# * Every worker path MUST live under <scope-dir> (no cross-scope symlinks,
|
|
25
|
-
# which would break on pack install / hq-sync). Refuses otherwise.
|
|
26
|
-
# * If no canonical exists yet, the FIRST worker path is promoted to canonical.
|
|
27
|
-
# * A worker copy whose content DIFFERS from the canonical is a DRIFTED copy:
|
|
28
|
-
# the script refuses and tells you to reconcile by hand first (the human
|
|
29
|
-
# decision the design reserves — never a silent overwrite). Re-run after
|
|
30
|
-
# reconciling, or pass --force to accept the canonical for that copy.
|
|
31
|
-
# * Idempotent: a path already symlinked to the canonical is left alone.
|
|
32
|
-
# * DRY-RUN BY DEFAULT. Pass --apply to make changes.
|
|
33
|
-
|
|
34
|
-
set -euo pipefail
|
|
35
|
-
|
|
36
|
-
APPLY=0
|
|
37
|
-
FORCE=0
|
|
38
|
-
args=()
|
|
39
|
-
for a in "$@"; do
|
|
40
|
-
case "$a" in
|
|
41
|
-
--apply) APPLY=1 ;;
|
|
42
|
-
--force) FORCE=1 ;;
|
|
43
|
-
-*) echo "unknown flag: $a" >&2; exit 2 ;;
|
|
44
|
-
*) args+=("$a") ;;
|
|
45
|
-
esac
|
|
46
|
-
done
|
|
47
|
-
|
|
48
|
-
if [[ ${#args[@]} -lt 3 ]]; then
|
|
49
|
-
echo "usage: $0 [--apply] [--force] <scope-dir> <skill-name> <worker-skill-path>..." >&2
|
|
50
|
-
exit 2
|
|
51
|
-
fi
|
|
52
|
-
|
|
53
|
-
repo_root="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
|
|
54
|
-
cd "$repo_root"
|
|
55
|
-
|
|
56
|
-
scope_dir="${args[0]%/}"
|
|
57
|
-
skill_name="${args[1]}"
|
|
58
|
-
worker_paths=("${args[@]:2}")
|
|
59
|
-
|
|
60
|
-
if [[ ! "$skill_name" =~ ^[A-Za-z0-9][A-Za-z0-9._-]*$ ]]; then
|
|
61
|
-
echo "error: skill-name '$skill_name' is not a bare skill name (no slashes, no .md)" >&2
|
|
62
|
-
exit 2
|
|
63
|
-
fi
|
|
64
|
-
if [[ ! -d "$scope_dir" ]]; then
|
|
65
|
-
echo "error: scope dir does not exist: $scope_dir" >&2
|
|
66
|
-
exit 2
|
|
67
|
-
fi
|
|
68
|
-
|
|
69
|
-
canonical="$scope_dir/_shared-skills/$skill_name.md"
|
|
70
|
-
|
|
71
|
-
note() { printf '%s\n' "$*"; }
|
|
72
|
-
would() { if [[ $APPLY -eq 1 ]]; then note " did: $*"; else note " would: $*"; fi; }
|
|
73
|
-
|
|
74
|
-
# Normalize a path to repo-relative without requiring GNU realpath (macOS-safe).
|
|
75
|
-
rel_under() { # rel_under <path> <dir> → 0 if <path> is inside <dir>
|
|
76
|
-
local p="${1#./}" d="${2#./}"
|
|
77
|
-
[[ "$p" == "$d/"* ]]
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
# rel_path <from-dir> <to-file> → relative path from <from-dir> to <to-file>,
|
|
81
|
-
# computed purely from the two repo-relative strings (both already normalized,
|
|
82
|
-
# no `..` segments, no symlinks in the literal path). Portable: no python3, no
|
|
83
|
-
# GNU realpath --relative-to (macOS ships neither).
|
|
84
|
-
rel_path() {
|
|
85
|
-
local from="${1#./}" to="${2#./}"
|
|
86
|
-
local -a fa ta
|
|
87
|
-
IFS='/' read -r -a fa <<< "$from"
|
|
88
|
-
IFS='/' read -r -a ta <<< "$to"
|
|
89
|
-
local i=0
|
|
90
|
-
while [[ $i -lt ${#fa[@]} && $i -lt ${#ta[@]} && "${fa[$i]}" == "${ta[$i]}" ]]; do
|
|
91
|
-
i=$((i + 1))
|
|
92
|
-
done
|
|
93
|
-
local up="" j
|
|
94
|
-
for (( j=i; j<${#fa[@]}; j++ )); do up="../$up"; done
|
|
95
|
-
local down="" k
|
|
96
|
-
for (( k=i; k<${#ta[@]}; k++ )); do down="$down${ta[$k]}/"; done
|
|
97
|
-
down="${down%/}"
|
|
98
|
-
printf '%s%s' "$up" "$down"
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
# Every worker path must be inside the scope dir.
|
|
102
|
-
for wp in "${worker_paths[@]}"; do
|
|
103
|
-
wp="${wp#./}"
|
|
104
|
-
if ! rel_under "$wp" "$scope_dir"; then
|
|
105
|
-
echo "error: worker path '$wp' is not under scope dir '$scope_dir'" >&2
|
|
106
|
-
echo " canonical must live in the narrowest scope covering all sharers;" >&2
|
|
107
|
-
echo " cross-scope symlinks are disallowed. Aborting (no changes made)." >&2
|
|
108
|
-
exit 2
|
|
109
|
-
fi
|
|
110
|
-
done
|
|
111
|
-
|
|
112
|
-
note "Canonical: $canonical"
|
|
113
|
-
note "Scope: $scope_dir"
|
|
114
|
-
[[ $APPLY -eq 1 ]] || note "(dry run — pass --apply to make changes)"
|
|
115
|
-
|
|
116
|
-
# 1) Establish the canonical file.
|
|
117
|
-
if [[ -e "$canonical" && ! -L "$canonical" ]]; then
|
|
118
|
-
note "canonical already exists (regular file) — reusing it"
|
|
119
|
-
else
|
|
120
|
-
# Promote the first worker path that is a real (non-symlink) file.
|
|
121
|
-
seed=""
|
|
122
|
-
for wp in "${worker_paths[@]}"; do
|
|
123
|
-
if [[ -f "$wp" && ! -L "$wp" ]]; then seed="$wp"; break; fi
|
|
124
|
-
done
|
|
125
|
-
if [[ -z "$seed" ]]; then
|
|
126
|
-
echo "error: no canonical exists and no worker path is a regular file to seed it from" >&2
|
|
127
|
-
exit 2
|
|
128
|
-
fi
|
|
129
|
-
would "mkdir -p $scope_dir/_shared-skills"
|
|
130
|
-
would "git mv $seed $canonical (promote first copy to canonical)"
|
|
131
|
-
if [[ $APPLY -eq 1 ]]; then
|
|
132
|
-
mkdir -p "$scope_dir/_shared-skills"
|
|
133
|
-
git mv "$seed" "$canonical" 2>/dev/null || mv "$seed" "$canonical"
|
|
134
|
-
fi
|
|
135
|
-
fi
|
|
136
|
-
|
|
137
|
-
# 2) Point each worker path at the canonical via a relative symlink.
|
|
138
|
-
for wp in "${worker_paths[@]}"; do
|
|
139
|
-
wp="${wp#./}"
|
|
140
|
-
# Already the canonical file itself (post-promotion) → link it too so every
|
|
141
|
-
# worker slot is a symlink and the canonical lives only under _shared-skills.
|
|
142
|
-
target_dir="$(dirname "$wp")"
|
|
143
|
-
# Relative path from the worker's skills dir to the canonical (portable).
|
|
144
|
-
rel="$(rel_path "$target_dir" "$canonical")"
|
|
145
|
-
|
|
146
|
-
if [[ -L "$wp" ]]; then
|
|
147
|
-
cur="$(readlink "$wp")"
|
|
148
|
-
if [[ "$cur" == "$rel" ]]; then
|
|
149
|
-
note "ok: $wp already links to canonical"
|
|
150
|
-
continue
|
|
151
|
-
fi
|
|
152
|
-
would "relink $wp -> $rel (was: $cur)"
|
|
153
|
-
if [[ $APPLY -eq 1 ]]; then ln -sfn "$rel" "$wp"; fi
|
|
154
|
-
continue
|
|
155
|
-
fi
|
|
156
|
-
|
|
157
|
-
if [[ -e "$wp" ]]; then
|
|
158
|
-
# Regular file present — must match canonical or be reconciled first.
|
|
159
|
-
if cmp -s "$wp" "$canonical"; then
|
|
160
|
-
would "replace identical copy $wp with symlink -> $rel"
|
|
161
|
-
if [[ $APPLY -eq 1 ]]; then rm -f "$wp"; ln -s "$rel" "$wp"; fi
|
|
162
|
-
else
|
|
163
|
-
if [[ $FORCE -eq 1 ]]; then
|
|
164
|
-
would "FORCE replace DRIFTED copy $wp with symlink -> $rel (content discarded)"
|
|
165
|
-
if [[ $APPLY -eq 1 ]]; then rm -f "$wp"; ln -s "$rel" "$wp"; fi
|
|
166
|
-
else
|
|
167
|
-
echo " DRIFT: $wp differs from canonical — reconcile by hand, then re-run" >&2
|
|
168
|
-
echo " (diff $wp $canonical), or pass --force to accept canonical." >&2
|
|
169
|
-
exit 3
|
|
170
|
-
fi
|
|
171
|
-
fi
|
|
172
|
-
else
|
|
173
|
-
would "create symlink $wp -> $rel"
|
|
174
|
-
if [[ $APPLY -eq 1 ]]; then mkdir -p "$target_dir"; ln -s "$rel" "$wp"; fi
|
|
175
|
-
fi
|
|
176
|
-
done
|
|
177
|
-
|
|
178
|
-
note "done."
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
/** Default-off rollout gate for native worker-scoped skill commands. */
|
|
2
|
-
export declare const CORE_NATIVE_WORKER_SKILLS_FLAG = "core-native-worker-skills";
|
|
3
|
-
export declare function coreNativeWorkerSkillsEnabled(): Promise<boolean>;
|
|
4
|
-
//# sourceMappingURL=core-native-worker-skills-flag.d.ts.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/** Default-off rollout gate for native worker-scoped skill commands. */
|
|
2
|
-
export const CORE_NATIVE_WORKER_SKILLS_FLAG = "core-native-worker-skills";
|
|
3
|
-
export async function coreNativeWorkerSkillsEnabled() {
|
|
4
|
-
const { resolveProcessFlagGate } = await import("../lib/flag-registry.js");
|
|
5
|
-
return resolveProcessFlagGate(CORE_NATIVE_WORKER_SKILLS_FLAG, { fallback: false }, () => false);
|
|
6
|
-
}
|
|
7
|
-
//# sourceMappingURL=core-native-worker-skills-flag.js.map
|