@codyswann/lisa 4.27.3 → 4.27.5
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/all/copy-overwrite/scripts/lisa-work-item.mjs +167 -2
- package/cdk/create-only/.github/workflows/ci.yml +79 -4
- package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.js +6 -0
- package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
- package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +11 -5
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/dist/migrations/ensure-push-default-safe.d.ts +50 -0
- package/dist/migrations/ensure-push-default-safe.d.ts.map +1 -0
- package/dist/migrations/ensure-push-default-safe.js +159 -0
- package/dist/migrations/ensure-push-default-safe.js.map +1 -0
- package/dist/migrations/index.d.ts +1 -0
- package/dist/migrations/index.d.ts.map +1 -1
- package/dist/migrations/index.js +3 -0
- package/dist/migrations/index.js.map +1 -1
- package/package.json +3 -3
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-sync-down/SKILL.md +8 -1
- package/plugins/lisa/skills/lisa-sync-down/SKILL.md +8 -1
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/lisa-sync-down/SKILL.md +8 -1
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/skills/lisa-sync-down/SKILL.md +8 -1
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/skills/lisa-sync-down/SKILL.md +8 -1
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/src/base/skills/lisa-sync-down/SKILL.md +8 -1
- package/scripts/lisa-commit-and-pr-local.sh +22 -6
- package/typescript/copy-contents/.husky/pre-push +70 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "4.27.
|
|
3
|
+
"version": "4.27.5",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "4.27.
|
|
3
|
+
"version": "4.27.5",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, across Claude and Codex.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "4.27.
|
|
3
|
+
"version": "4.27.5",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "4.27.
|
|
3
|
+
"version": "4.27.5",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "4.27.
|
|
3
|
+
"version": "4.27.5",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -127,8 +127,15 @@ source-only work downward.
|
|
|
127
127
|
If residue remains after applying the appropriate pattern, abort that hop and
|
|
128
128
|
report the unresolved files and the evidence gathered. Do not silently choose
|
|
129
129
|
source-wins when the target may already contain the change or has moved the code.
|
|
130
|
-
5. **Push** the sync branch
|
|
130
|
+
5. **Push** the sync branch with a fully qualified destination refspec:
|
|
131
|
+
`git push origin sync/<source>-to-<target>:refs/heads/sync/<source>-to-<target> --force-with-lease`.
|
|
131
132
|
Only ever force-push the sync branch — never the target environment branch.
|
|
133
|
+
The refspec is not decoration. `push -u origin <branch>` names only a
|
|
134
|
+
source, so git resolves the destination from the branch's upstream; where
|
|
135
|
+
`push.default` is `upstream` and the sync branch was created from the
|
|
136
|
+
target, that resolves to the TARGET ENVIRONMENT BRANCH and a force-push
|
|
137
|
+
lands there (CodySwannGT/lisa#3495). Naming the destination in full is
|
|
138
|
+
what makes the sentence above enforceable rather than advisory.
|
|
132
139
|
6. **Open or update the PR.** Check for an existing open PR
|
|
133
140
|
(`gh pr list --head sync/<source>-to-<target> --base <target> --state open`).
|
|
134
141
|
Update its body if it exists, otherwise create it
|
|
@@ -148,9 +148,18 @@ while IFS=$'\t' read -r project_path target_branch; do
|
|
|
148
148
|
continue
|
|
149
149
|
fi
|
|
150
150
|
|
|
151
|
-
# Create branch
|
|
151
|
+
# Create branch.
|
|
152
|
+
#
|
|
153
|
+
# `--no-track` is load-bearing, not tidiness. Without it the new branch
|
|
154
|
+
# inherits "$target_branch" as its upstream, and in any repository where
|
|
155
|
+
# push.default is "upstream" or "tracking" git resolves a push's destination
|
|
156
|
+
# from that upstream rather than from the branch name — so the push below
|
|
157
|
+
# would land on the environment branch itself, bypassing branch protection
|
|
158
|
+
# and every required check, while reporting success (CodySwannGT/lisa#3495).
|
|
159
|
+
# This script runs across a whole fleet of repositories at once, so it cannot
|
|
160
|
+
# assume any one of them has a safe push.default.
|
|
152
161
|
log_info "Creating branch: $branch_name"
|
|
153
|
-
if ! git -C "$expanded_path"
|
|
162
|
+
if ! git -C "$expanded_path" switch -c "$branch_name" --no-track "$target_branch" 2>&1; then
|
|
154
163
|
log_error "Failed to create branch $branch_name in $expanded_path"
|
|
155
164
|
((fail_count++)) || true
|
|
156
165
|
continue
|
|
@@ -169,17 +178,24 @@ while IFS=$'\t' read -r project_path target_branch; do
|
|
|
169
178
|
continue
|
|
170
179
|
fi
|
|
171
180
|
|
|
172
|
-
# Push
|
|
181
|
+
# Push with a FULLY QUALIFIED destination refspec. `push -u origin <branch>`
|
|
182
|
+
# names only a source, which leaves the destination for push.default to
|
|
183
|
+
# resolve; `<branch>:refs/heads/<branch>` states it, so no config can move it.
|
|
184
|
+
# Belt and braces with --no-track above: either alone closes the hole, and
|
|
185
|
+
# this script has no way to verify which of them a given host repository
|
|
186
|
+
# needed.
|
|
173
187
|
log_info "Pushing to origin/$branch_name..."
|
|
174
|
-
if ! GIT_SSH_COMMAND="ssh -o ServerAliveInterval=30 -o ServerAliveCountMax=5" git -C "$expanded_path" push
|
|
188
|
+
if ! GIT_SSH_COMMAND="ssh -o ServerAliveInterval=30 -o ServerAliveCountMax=5" git -C "$expanded_path" push origin "$branch_name:refs/heads/$branch_name" 2>&1; then
|
|
175
189
|
log_error "Failed to push $branch_name in $expanded_path"
|
|
176
190
|
((fail_count++)) || true
|
|
177
191
|
continue
|
|
178
192
|
fi
|
|
179
193
|
|
|
180
|
-
# Create PR
|
|
194
|
+
# Create PR. `--head` is explicit because the push above deliberately does not
|
|
195
|
+
# set an upstream, and without one `gh` would fall back to guessing (or
|
|
196
|
+
# prompting for) the head branch.
|
|
181
197
|
log_info "Creating pull request..."
|
|
182
|
-
if ! (cd "$expanded_path" && gh pr create --title "chore: update Lisa configuration" --base "$target_branch" --body "Automated Lisa configuration update applied on $DATE_STAMP."); then
|
|
198
|
+
if ! (cd "$expanded_path" && gh pr create --title "chore: update Lisa configuration" --base "$target_branch" --head "$branch_name" --body "Automated Lisa configuration update applied on $DATE_STAMP."); then
|
|
183
199
|
log_error "Failed to create PR for $expanded_path"
|
|
184
200
|
((fail_count++)) || true
|
|
185
201
|
continue
|
|
@@ -87,6 +87,76 @@ if ! command -v node >/dev/null 2>&1; then
|
|
|
87
87
|
echo "❌ Push blocked: Node.js is required to validate tracker work items."
|
|
88
88
|
exit 1
|
|
89
89
|
fi
|
|
90
|
+
|
|
91
|
+
# BEGIN: push destination guard
|
|
92
|
+
# ---------------------------------------------------------------------------
|
|
93
|
+
# Refuse a push whose RESOLVED destination is a deploy branch it was not aimed
|
|
94
|
+
# at.
|
|
95
|
+
#
|
|
96
|
+
# `push.default=upstream` (and its deprecated spelling `tracking`) resolves a
|
|
97
|
+
# push's destination from the branch's UPSTREAM rather than from the branch
|
|
98
|
+
# named on the command line. A working branch created the ordinary way —
|
|
99
|
+
# `git checkout -b <branch> origin/main` — has `main` as its upstream, so the
|
|
100
|
+
# ordinary `git push -u origin <branch>` resolves to `refs/heads/main` and lands
|
|
101
|
+
# there. The push reports success. Branch protection and every required check
|
|
102
|
+
# are bypassed, and the operator is told only afterwards, if at all
|
|
103
|
+
# (CodySwannGT/lisa#3495).
|
|
104
|
+
#
|
|
105
|
+
# Measured in Lisa's own repository: two commits reached the default branch this
|
|
106
|
+
# way. Every detection control afterwards fired correctly — the bypass was
|
|
107
|
+
# reported, an agent force-push was refused, the release run was caught and
|
|
108
|
+
# cancelled — and the commits shipped in a published release regardless, because
|
|
109
|
+
# an ordinary unrelated merge cut a release before anyone could rewind. Nothing
|
|
110
|
+
# had prevented the original push. That is why this is a refusal and not a
|
|
111
|
+
# warning.
|
|
112
|
+
#
|
|
113
|
+
# WHY HERE, and not folded into a check that already exists.
|
|
114
|
+
#
|
|
115
|
+
# It reads the RESOLVED DESTINATION, in the third field of the stdin lines. That
|
|
116
|
+
# is the only place in the system where the destination git actually chose is
|
|
117
|
+
# observable; `push.default`, the branch's upstream and the command line are all
|
|
118
|
+
# proxies for it, and the accident is precisely a disagreement between the
|
|
119
|
+
# proxies and the answer. So the check has to live at the push moment, on this
|
|
120
|
+
# stream.
|
|
121
|
+
#
|
|
122
|
+
# It is UNCONDITIONAL. The traceability step below stands down when a project
|
|
123
|
+
# declares `gates.traceability`, and a guard a declaration can switch off is not
|
|
124
|
+
# a guard against an accident. It also runs BELOW the deletion-only guard, which
|
|
125
|
+
# exits first, so deleting a branch still needs no node.
|
|
126
|
+
#
|
|
127
|
+
# WHAT IT ALLOWS, deliberately: `main -> main`, so a merge landed locally still
|
|
128
|
+
# pushes; a `HEAD` local ref, which is how git spells a destination the pusher
|
|
129
|
+
# wrote out in full and how release automation pushes from a detached checkout;
|
|
130
|
+
# and every push whose destination is not a deploy branch at all.
|
|
131
|
+
#
|
|
132
|
+
# READING THE STREAM SPENDS IT — the same constraint the deletion guard above
|
|
133
|
+
# documents, and the same remedy: capture, use, replay with `exec <`. If no
|
|
134
|
+
# scratch file can be created this stands down without reading a byte, leaving
|
|
135
|
+
# the hook exactly as it was; a guard that cannot read the stream must not also
|
|
136
|
+
# starve the checks that can.
|
|
137
|
+
# ---------------------------------------------------------------------------
|
|
138
|
+
#
|
|
139
|
+
# The `-f` test is not belt and braces. This is now the FIRST thing in the file
|
|
140
|
+
# to invoke the validator, so a checkout where no candidate path exists would
|
|
141
|
+
# fail every push with a Node module-resolution error instead of the hook's own
|
|
142
|
+
# message. Standing down leaves that diagnosis to the traceability step below,
|
|
143
|
+
# which owns it and words it properly.
|
|
144
|
+
LISA_DEST_REFS="$(mktemp "${TMPDIR:-/tmp}/lisa-dest-refs.XXXXXXXX")" || LISA_DEST_REFS=""
|
|
145
|
+
if [ -n "$LISA_DEST_REFS" ] && [ -f "$WORK_ITEM_SCRIPT" ]; then
|
|
146
|
+
cat > "$LISA_DEST_REFS"
|
|
147
|
+
if ! node "$WORK_ITEM_SCRIPT" validate-push-destination "${1:-origin}" --refs "$LISA_DEST_REFS"; then
|
|
148
|
+
rm -f "$LISA_DEST_REFS"
|
|
149
|
+
exit 1
|
|
150
|
+
fi
|
|
151
|
+
# Put the stream back, byte for byte, for the validator and every gate below.
|
|
152
|
+
exec < "$LISA_DEST_REFS"
|
|
153
|
+
# Unlinked while the descriptor above is still open, so nothing is left in
|
|
154
|
+
# TMPDIR and no later `trap ... EXIT` in this file can drop the cleanup.
|
|
155
|
+
rm -f "$LISA_DEST_REFS"
|
|
156
|
+
fi
|
|
157
|
+
unset LISA_DEST_REFS
|
|
158
|
+
# END: push destination guard
|
|
159
|
+
|
|
90
160
|
# ---------------------------------------------------------------------------
|
|
91
161
|
# Work-item traceability, at the push moment.
|
|
92
162
|
#
|