@codyswann/lisa 4.22.8 → 4.22.10
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/lib/process-tree-runner.mjs +127 -0
- package/all/copy-overwrite/scripts/lisa-floor-collisions.mjs +63 -8
- package/all/copy-overwrite/scripts/lisa-hooks/parity-safety-net.sh +36 -6
- package/all/copy-overwrite/scripts/lisa-postinstall.mjs +35 -13
- package/all/copy-overwrite/scripts/lisa-reconcile-policy.mjs +11 -3
- package/all/copy-overwrite/scripts/lisa-run-gates.mjs +41 -8
- package/all/copy-overwrite/scripts/lisa-schema-validate.mjs +2 -2
- package/all/copy-overwrite/scripts/lisa-work-item.mjs +2 -1
- package/cdk/package-lisa/package.lisa.json +1 -1
- package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.js +24 -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/nightly-e2e-guard-behavior-certificate.js.map +1 -1
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +61 -51
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/dist/opencode/plugin-templates/parity-safety-net.sh +36 -6
- package/nestjs/package-lisa/package.lisa.json +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-atlassian-access/SKILL.md +10 -13
- package/plugins/lisa/.codex-plugin/skills/lisa-doctor/SKILL.md +4 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-drive-pr-to-merge/SKILL.md +29 -4
- package/plugins/lisa/.codex-plugin/skills/lisa-github-sync/SKILL.md +8 -3
- package/plugins/lisa/.codex-plugin/skills/lisa-jam-access/SKILL.md +7 -10
- package/plugins/lisa/.codex-plugin/skills/lisa-jira-journey/SKILL.md +5 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-jira-journey/scripts/parse-plan.py +36 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-jira-sync/SKILL.md +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-access/SKILL.md +8 -12
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-sync/SKILL.md +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-nightly-lower-code-complexity/SKILL.md +7 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-notion-access/SKILL.md +7 -10
- package/plugins/lisa/.codex-plugin/skills/lisa-posthog-access/SKILL.md +7 -10
- package/plugins/lisa/.codex-plugin/skills/lisa-repair-intake/SKILL.md +19 -3
- package/plugins/lisa/.codex-plugin/skills/lisa-secrets-access/scripts/materialize-secrets.mjs +10 -6
- package/plugins/lisa/.codex-plugin/skills/lisa-secrets-access/scripts/publish-aws-bootstrap.mjs +95 -44
- package/plugins/lisa/.codex-plugin/skills/lisa-sentry-access/SKILL.md +7 -10
- package/plugins/lisa/.codex-plugin/skills/lisa-setup-atlassian/SKILL.md +7 -10
- package/plugins/lisa/.codex-plugin/skills/lisa-setup-linear/SKILL.md +9 -12
- package/plugins/lisa/.codex-plugin/skills/lisa-setup-notion/SKILL.md +7 -10
- package/plugins/lisa/.codex-plugin/skills/lisa-setup-remote-aws/SKILL.md +7 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-setup-remote-env/SKILL.md +6 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-setup-remote-env/assets/session-start.sh +19 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-setup-remote-env/assets/setup.sh +1 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +25 -4
- package/plugins/lisa/.codex-plugin/skills/lisa-setup-workstation/scripts/bounded-child.mjs +9 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-setup-workstation/scripts/workstation.mjs +29 -21
- package/plugins/lisa/.codex-plugin/skills/lisa-sonarcloud-access/SKILL.md +7 -10
- package/plugins/lisa/.codex-plugin/skills/lisa-tracker-sync/SKILL.md +1 -1
- package/plugins/lisa/hooks/parity-safety-net.sh +36 -6
- package/plugins/lisa/hooks/threshold-ratchet-families.mjs +31 -7
- package/plugins/lisa/rules/reference/base-rules.md +1 -1
- package/plugins/lisa/rules/reference/config-resolution.md +5 -14
- package/plugins/lisa/scripts/install-remote-agent-aws.mjs +5 -1
- package/plugins/lisa/scripts/rollup-blocker-classification.mjs +18 -3
- package/plugins/lisa/skills/lisa-atlassian-access/SKILL.md +10 -13
- package/plugins/lisa/skills/lisa-doctor/SKILL.md +4 -2
- package/plugins/lisa/skills/lisa-drive-pr-to-merge/SKILL.md +29 -4
- package/plugins/lisa/skills/lisa-github-sync/SKILL.md +8 -3
- package/plugins/lisa/skills/lisa-jam-access/SKILL.md +7 -10
- package/plugins/lisa/skills/lisa-jira-journey/SKILL.md +5 -0
- package/plugins/lisa/skills/lisa-jira-journey/scripts/parse-plan.py +36 -2
- package/plugins/lisa/skills/lisa-jira-sync/SKILL.md +1 -1
- package/plugins/lisa/skills/lisa-linear-access/SKILL.md +8 -12
- package/plugins/lisa/skills/lisa-linear-sync/SKILL.md +1 -1
- package/plugins/lisa/skills/lisa-nightly-lower-code-complexity/SKILL.md +7 -1
- package/plugins/lisa/skills/lisa-notion-access/SKILL.md +7 -10
- package/plugins/lisa/skills/lisa-posthog-access/SKILL.md +7 -10
- package/plugins/lisa/skills/lisa-repair-intake/SKILL.md +19 -3
- package/plugins/lisa/skills/lisa-secrets-access/scripts/materialize-secrets.mjs +10 -6
- package/plugins/lisa/skills/lisa-secrets-access/scripts/publish-aws-bootstrap.mjs +95 -44
- package/plugins/lisa/skills/lisa-sentry-access/SKILL.md +7 -10
- package/plugins/lisa/skills/lisa-setup-atlassian/SKILL.md +7 -10
- package/plugins/lisa/skills/lisa-setup-linear/SKILL.md +9 -12
- package/plugins/lisa/skills/lisa-setup-notion/SKILL.md +7 -10
- package/plugins/lisa/skills/lisa-setup-remote-aws/SKILL.md +7 -2
- package/plugins/lisa/skills/lisa-setup-remote-env/SKILL.md +6 -1
- package/plugins/lisa/skills/lisa-setup-remote-env/assets/session-start.sh +19 -0
- package/plugins/lisa/skills/lisa-setup-remote-env/assets/setup.sh +1 -0
- package/plugins/lisa/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +25 -4
- package/plugins/lisa/skills/lisa-setup-workstation/scripts/bounded-child.mjs +9 -0
- package/plugins/lisa/skills/lisa-setup-workstation/scripts/workstation.mjs +29 -21
- package/plugins/lisa/skills/lisa-sonarcloud-access/SKILL.md +7 -10
- package/plugins/lisa/skills/lisa-tracker-sync/SKILL.md +1 -1
- package/plugins/lisa-agy/hooks/parity-safety-net.sh +36 -6
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/scripts/install-remote-agent-aws.mjs +5 -1
- package/plugins/lisa-agy/scripts/rollup-blocker-classification.mjs +18 -3
- package/plugins/lisa-agy/skills/lisa-atlassian-access/SKILL.md +10 -13
- package/plugins/lisa-agy/skills/lisa-doctor/SKILL.md +4 -2
- package/plugins/lisa-agy/skills/lisa-drive-pr-to-merge/SKILL.md +29 -4
- package/plugins/lisa-agy/skills/lisa-github-sync/SKILL.md +8 -3
- package/plugins/lisa-agy/skills/lisa-jam-access/SKILL.md +7 -10
- package/plugins/lisa-agy/skills/lisa-jira-journey/SKILL.md +5 -0
- package/plugins/lisa-agy/skills/lisa-jira-journey/scripts/parse-plan.py +36 -2
- package/plugins/lisa-agy/skills/lisa-jira-sync/SKILL.md +1 -1
- package/plugins/lisa-agy/skills/lisa-linear-access/SKILL.md +8 -12
- package/plugins/lisa-agy/skills/lisa-linear-sync/SKILL.md +1 -1
- package/plugins/lisa-agy/skills/lisa-nightly-lower-code-complexity/SKILL.md +7 -1
- package/plugins/lisa-agy/skills/lisa-notion-access/SKILL.md +7 -10
- package/plugins/lisa-agy/skills/lisa-posthog-access/SKILL.md +7 -10
- package/plugins/lisa-agy/skills/lisa-repair-intake/SKILL.md +19 -3
- package/plugins/lisa-agy/skills/lisa-secrets-access/scripts/materialize-secrets.mjs +10 -6
- package/plugins/lisa-agy/skills/lisa-secrets-access/scripts/publish-aws-bootstrap.mjs +95 -44
- package/plugins/lisa-agy/skills/lisa-sentry-access/SKILL.md +7 -10
- package/plugins/lisa-agy/skills/lisa-setup-atlassian/SKILL.md +7 -10
- package/plugins/lisa-agy/skills/lisa-setup-linear/SKILL.md +9 -12
- package/plugins/lisa-agy/skills/lisa-setup-notion/SKILL.md +7 -10
- package/plugins/lisa-agy/skills/lisa-setup-remote-aws/SKILL.md +7 -2
- package/plugins/lisa-agy/skills/lisa-setup-remote-env/SKILL.md +6 -1
- package/plugins/lisa-agy/skills/lisa-setup-remote-env/assets/session-start.sh +19 -0
- package/plugins/lisa-agy/skills/lisa-setup-remote-env/assets/setup.sh +1 -0
- package/plugins/lisa-agy/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +25 -4
- package/plugins/lisa-agy/skills/lisa-setup-workstation/scripts/bounded-child.mjs +9 -0
- package/plugins/lisa-agy/skills/lisa-setup-workstation/scripts/workstation.mjs +29 -21
- package/plugins/lisa-agy/skills/lisa-sonarcloud-access/SKILL.md +7 -10
- package/plugins/lisa-agy/skills/lisa-tracker-sync/SKILL.md +1 -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/hooks/parity-safety-net.sh +36 -6
- package/plugins/lisa-copilot/hooks/threshold-ratchet-families.mjs +31 -7
- package/plugins/lisa-copilot/rules/reference/base-rules.md +1 -1
- package/plugins/lisa-copilot/rules/reference/config-resolution.md +5 -14
- package/plugins/lisa-copilot/scripts/install-remote-agent-aws.mjs +5 -1
- package/plugins/lisa-copilot/scripts/rollup-blocker-classification.mjs +18 -3
- package/plugins/lisa-copilot/skills/lisa-atlassian-access/SKILL.md +10 -13
- package/plugins/lisa-copilot/skills/lisa-doctor/SKILL.md +4 -2
- package/plugins/lisa-copilot/skills/lisa-drive-pr-to-merge/SKILL.md +29 -4
- package/plugins/lisa-copilot/skills/lisa-github-sync/SKILL.md +8 -3
- package/plugins/lisa-copilot/skills/lisa-jam-access/SKILL.md +7 -10
- package/plugins/lisa-copilot/skills/lisa-jira-journey/SKILL.md +5 -0
- package/plugins/lisa-copilot/skills/lisa-jira-journey/scripts/parse-plan.py +36 -2
- package/plugins/lisa-copilot/skills/lisa-jira-sync/SKILL.md +1 -1
- package/plugins/lisa-copilot/skills/lisa-linear-access/SKILL.md +8 -12
- package/plugins/lisa-copilot/skills/lisa-linear-sync/SKILL.md +1 -1
- package/plugins/lisa-copilot/skills/lisa-nightly-lower-code-complexity/SKILL.md +7 -1
- package/plugins/lisa-copilot/skills/lisa-notion-access/SKILL.md +7 -10
- package/plugins/lisa-copilot/skills/lisa-posthog-access/SKILL.md +7 -10
- package/plugins/lisa-copilot/skills/lisa-repair-intake/SKILL.md +19 -3
- package/plugins/lisa-copilot/skills/lisa-secrets-access/scripts/materialize-secrets.mjs +10 -6
- package/plugins/lisa-copilot/skills/lisa-secrets-access/scripts/publish-aws-bootstrap.mjs +95 -44
- package/plugins/lisa-copilot/skills/lisa-sentry-access/SKILL.md +7 -10
- package/plugins/lisa-copilot/skills/lisa-setup-atlassian/SKILL.md +7 -10
- package/plugins/lisa-copilot/skills/lisa-setup-linear/SKILL.md +9 -12
- package/plugins/lisa-copilot/skills/lisa-setup-notion/SKILL.md +7 -10
- package/plugins/lisa-copilot/skills/lisa-setup-remote-aws/SKILL.md +7 -2
- package/plugins/lisa-copilot/skills/lisa-setup-remote-env/SKILL.md +6 -1
- package/plugins/lisa-copilot/skills/lisa-setup-remote-env/assets/session-start.sh +19 -0
- package/plugins/lisa-copilot/skills/lisa-setup-remote-env/assets/setup.sh +1 -0
- package/plugins/lisa-copilot/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +25 -4
- package/plugins/lisa-copilot/skills/lisa-setup-workstation/scripts/bounded-child.mjs +9 -0
- package/plugins/lisa-copilot/skills/lisa-setup-workstation/scripts/workstation.mjs +29 -21
- package/plugins/lisa-copilot/skills/lisa-sonarcloud-access/SKILL.md +7 -10
- package/plugins/lisa-copilot/skills/lisa-tracker-sync/SKILL.md +1 -1
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/hooks/parity-safety-net.sh +36 -6
- package/plugins/lisa-cursor/hooks/threshold-ratchet-families.mjs +31 -7
- package/plugins/lisa-cursor/rules/base-rules-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/config-resolution-reference.mdc +5 -14
- package/plugins/lisa-cursor/scripts/install-remote-agent-aws.mjs +5 -1
- package/plugins/lisa-cursor/scripts/rollup-blocker-classification.mjs +18 -3
- package/plugins/lisa-cursor/skills/lisa-atlassian-access/SKILL.md +10 -13
- package/plugins/lisa-cursor/skills/lisa-doctor/SKILL.md +4 -2
- package/plugins/lisa-cursor/skills/lisa-drive-pr-to-merge/SKILL.md +29 -4
- package/plugins/lisa-cursor/skills/lisa-github-sync/SKILL.md +8 -3
- package/plugins/lisa-cursor/skills/lisa-jam-access/SKILL.md +7 -10
- package/plugins/lisa-cursor/skills/lisa-jira-journey/SKILL.md +5 -0
- package/plugins/lisa-cursor/skills/lisa-jira-journey/scripts/parse-plan.py +36 -2
- package/plugins/lisa-cursor/skills/lisa-jira-sync/SKILL.md +1 -1
- package/plugins/lisa-cursor/skills/lisa-linear-access/SKILL.md +8 -12
- package/plugins/lisa-cursor/skills/lisa-linear-sync/SKILL.md +1 -1
- package/plugins/lisa-cursor/skills/lisa-nightly-lower-code-complexity/SKILL.md +7 -1
- package/plugins/lisa-cursor/skills/lisa-notion-access/SKILL.md +7 -10
- package/plugins/lisa-cursor/skills/lisa-posthog-access/SKILL.md +7 -10
- package/plugins/lisa-cursor/skills/lisa-repair-intake/SKILL.md +19 -3
- package/plugins/lisa-cursor/skills/lisa-secrets-access/scripts/materialize-secrets.mjs +10 -6
- package/plugins/lisa-cursor/skills/lisa-secrets-access/scripts/publish-aws-bootstrap.mjs +95 -44
- package/plugins/lisa-cursor/skills/lisa-sentry-access/SKILL.md +7 -10
- package/plugins/lisa-cursor/skills/lisa-setup-atlassian/SKILL.md +7 -10
- package/plugins/lisa-cursor/skills/lisa-setup-linear/SKILL.md +9 -12
- package/plugins/lisa-cursor/skills/lisa-setup-notion/SKILL.md +7 -10
- package/plugins/lisa-cursor/skills/lisa-setup-remote-aws/SKILL.md +7 -2
- package/plugins/lisa-cursor/skills/lisa-setup-remote-env/SKILL.md +6 -1
- package/plugins/lisa-cursor/skills/lisa-setup-remote-env/assets/session-start.sh +19 -0
- package/plugins/lisa-cursor/skills/lisa-setup-remote-env/assets/setup.sh +1 -0
- package/plugins/lisa-cursor/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +25 -4
- package/plugins/lisa-cursor/skills/lisa-setup-workstation/scripts/bounded-child.mjs +9 -0
- package/plugins/lisa-cursor/skills/lisa-setup-workstation/scripts/workstation.mjs +29 -21
- package/plugins/lisa-cursor/skills/lisa-sonarcloud-access/SKILL.md +7 -10
- package/plugins/lisa-cursor/skills/lisa-tracker-sync/SKILL.md +1 -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/hooks/parity-safety-net.sh +36 -6
- package/plugins/src/base/hooks/threshold-ratchet-families.mjs +31 -7
- package/plugins/src/base/rules/reference/base-rules.md +1 -1
- package/plugins/src/base/rules/reference/config-resolution.md +5 -14
- package/plugins/src/base/scripts/install-remote-agent-aws.mjs +5 -1
- package/plugins/src/base/scripts/rollup-blocker-classification.mjs +18 -3
- package/plugins/src/base/skills/lisa-atlassian-access/SKILL.md +10 -13
- package/plugins/src/base/skills/lisa-doctor/SKILL.md +4 -2
- package/plugins/src/base/skills/lisa-drive-pr-to-merge/SKILL.md +29 -4
- package/plugins/src/base/skills/lisa-github-sync/SKILL.md +8 -3
- package/plugins/src/base/skills/lisa-jam-access/SKILL.md +7 -10
- package/plugins/src/base/skills/lisa-jira-journey/SKILL.md +5 -0
- package/plugins/src/base/skills/lisa-jira-journey/scripts/parse-plan.py +36 -2
- package/plugins/src/base/skills/lisa-jira-sync/SKILL.md +1 -1
- package/plugins/src/base/skills/lisa-linear-access/SKILL.md +8 -12
- package/plugins/src/base/skills/lisa-linear-sync/SKILL.md +1 -1
- package/plugins/src/base/skills/lisa-nightly-lower-code-complexity/SKILL.md +7 -1
- package/plugins/src/base/skills/lisa-notion-access/SKILL.md +7 -10
- package/plugins/src/base/skills/lisa-posthog-access/SKILL.md +7 -10
- package/plugins/src/base/skills/lisa-repair-intake/SKILL.md +19 -3
- package/plugins/src/base/skills/lisa-secrets-access/scripts/materialize-secrets.mjs +10 -6
- package/plugins/src/base/skills/lisa-secrets-access/scripts/publish-aws-bootstrap.mjs +95 -44
- package/plugins/src/base/skills/lisa-sentry-access/SKILL.md +7 -10
- package/plugins/src/base/skills/lisa-setup-atlassian/SKILL.md +7 -10
- package/plugins/src/base/skills/lisa-setup-linear/SKILL.md +9 -12
- package/plugins/src/base/skills/lisa-setup-notion/SKILL.md +7 -10
- package/plugins/src/base/skills/lisa-setup-remote-aws/SKILL.md +7 -2
- package/plugins/src/base/skills/lisa-setup-remote-env/SKILL.md +6 -1
- package/plugins/src/base/skills/lisa-setup-remote-env/assets/session-start.sh +19 -0
- package/plugins/src/base/skills/lisa-setup-remote-env/assets/setup.sh +1 -0
- package/plugins/src/base/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +25 -4
- package/plugins/src/base/skills/lisa-setup-workstation/scripts/bounded-child.mjs +9 -0
- package/plugins/src/base/skills/lisa-setup-workstation/scripts/workstation.mjs +29 -21
- package/plugins/src/base/skills/lisa-sonarcloud-access/SKILL.md +7 -10
- package/plugins/src/base/skills/lisa-tracker-sync/SKILL.md +1 -1
- package/rails/copy-overwrite/scripts/threshold-ratchet-families.mjs +31 -7
- package/scripts/lisa-remote-env/session-start.sh +19 -0
- package/scripts/lisa-remote-env/setup.sh +1 -0
- package/scripts/two-channel-couplings.json +1 -1
- package/typescript/copy-contents/.husky/pre-push +1 -1
- package/typescript/copy-overwrite/scripts/threshold-ratchet-families.mjs +31 -7
- package/typescript/package-lisa/package.lisa.json +1 -1
package/plugins/lisa/.codex-plugin/skills/lisa-secrets-access/scripts/publish-aws-bootstrap.mjs
CHANGED
|
@@ -56,6 +56,11 @@ const ROLE_ARN =
|
|
|
56
56
|
/^arn:(?:aws|aws-us-gov|aws-cn):iam::\d{12}:role\/[\w+=,.@/-]+$/;
|
|
57
57
|
const PUBLICATION_COORDINATION_SCOPE = "AWS_BOOTSTRAP_";
|
|
58
58
|
const PUBLICATION_LOCK_TTL_MS = 30 * 60 * 1000;
|
|
59
|
+
// Every provider and AWS child has its own 30-second deadline. Stop starting
|
|
60
|
+
// target mutations five minutes before another publisher may reap this lock,
|
|
61
|
+
// leaving ample room for the in-flight child to finish. This is a monotonic
|
|
62
|
+
// duration budget, not a wall clock used to order or expire provider records.
|
|
63
|
+
const PUBLICATION_CRITICAL_SECTION_BUDGET_MS = 25 * 60 * 1000;
|
|
59
64
|
|
|
60
65
|
/**
|
|
61
66
|
* Validate and normalize one complete bundle without changing its serialized
|
|
@@ -257,6 +262,22 @@ function writeProviderValue(cfg, id, value, write) {
|
|
|
257
262
|
}
|
|
258
263
|
}
|
|
259
264
|
|
|
265
|
+
function publicationBudgetGuard(startedAt, monotonicNow) {
|
|
266
|
+
return () => {
|
|
267
|
+
const elapsed = monotonicNow() - startedAt;
|
|
268
|
+
if (!Number.isFinite(elapsed) || elapsed < 0) {
|
|
269
|
+
throw new Error(
|
|
270
|
+
"publication lock monotonic timer became invalid; refusing further provider mutation"
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
if (elapsed >= PUBLICATION_CRITICAL_SECTION_BUDGET_MS) {
|
|
274
|
+
throw new Error(
|
|
275
|
+
"publication lock execution budget exceeded; refusing further provider mutation"
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
|
|
260
281
|
/**
|
|
261
282
|
* Enter the provider election for one AWS bootstrap record.
|
|
262
283
|
*
|
|
@@ -427,23 +448,29 @@ export function releasePublicationLock(cfg, lock, operations = {}) {
|
|
|
427
448
|
* snapshot can never overwrite a publication that finished while this process
|
|
428
449
|
* was entering the election.
|
|
429
450
|
*/
|
|
430
|
-
function withPublicationLock(cfg, operations, task) {
|
|
451
|
+
function withPublicationLock(cfg, operations, task, completedMessage) {
|
|
431
452
|
const fetch = operations.fetch ?? fetchAll;
|
|
432
453
|
const acquire = operations.acquireLock ?? acquirePublicationLock;
|
|
433
454
|
const release = operations.releaseLock ?? releasePublicationLock;
|
|
455
|
+
const monotonicNow = operations.monotonicNow ?? (() => performance.now());
|
|
456
|
+
const startedAt = monotonicNow();
|
|
457
|
+
const assertWithinBudget = publicationBudgetGuard(startedAt, monotonicNow);
|
|
434
458
|
const target = currentEntry(cfg, fetch);
|
|
435
459
|
const lock = acquire(cfg, target, operations);
|
|
436
460
|
let result;
|
|
437
461
|
let taskError;
|
|
438
462
|
|
|
439
463
|
try {
|
|
464
|
+
assertWithinBudget();
|
|
440
465
|
const current = currentEntry(cfg, fetch);
|
|
441
466
|
if (current.id !== target.id || current.projectId !== target.projectId) {
|
|
442
467
|
throw new Error(
|
|
443
468
|
`${BOOTSTRAP_KEY} moved after publication lock acquisition; retry from the new provider record`
|
|
444
469
|
);
|
|
445
470
|
}
|
|
446
|
-
|
|
471
|
+
assertWithinBudget();
|
|
472
|
+
result = task(current, assertWithinBudget);
|
|
473
|
+
assertWithinBudget();
|
|
447
474
|
} catch (error) {
|
|
448
475
|
taskError = error;
|
|
449
476
|
}
|
|
@@ -455,15 +482,18 @@ function withPublicationLock(cfg, operations, task) {
|
|
|
455
482
|
if (taskError) {
|
|
456
483
|
throw new Error(`${firstLine(taskError)}; ${releaseReason}`);
|
|
457
484
|
}
|
|
458
|
-
throw new Error(
|
|
485
|
+
throw new Error(
|
|
486
|
+
`${completedMessage}; ${releaseReason}; remove the coordination record before the next publication`
|
|
487
|
+
);
|
|
459
488
|
}
|
|
460
489
|
|
|
461
490
|
if (taskError) throw taskError;
|
|
462
491
|
return result;
|
|
463
492
|
}
|
|
464
493
|
|
|
465
|
-
function preflightUnderLock(cfg, entry, write) {
|
|
494
|
+
function preflightUnderLock(cfg, entry, write, assertWithinBudget) {
|
|
466
495
|
try {
|
|
496
|
+
assertWithinBudget();
|
|
467
497
|
writeProviderValue(cfg, entry.id, entry.value, write);
|
|
468
498
|
} catch (error) {
|
|
469
499
|
throw new Error(
|
|
@@ -482,8 +512,12 @@ function preflightUnderLock(cfg, entry, write) {
|
|
|
482
512
|
*/
|
|
483
513
|
export function preflightAwsBootstrap(cfg, operations = {}) {
|
|
484
514
|
const write = operations.write ?? writeSecret;
|
|
485
|
-
return withPublicationLock(
|
|
486
|
-
|
|
515
|
+
return withPublicationLock(
|
|
516
|
+
cfg,
|
|
517
|
+
operations,
|
|
518
|
+
(entry, assertWithinBudget) =>
|
|
519
|
+
preflightUnderLock(cfg, entry, write, assertWithinBudget),
|
|
520
|
+
"preflight completed"
|
|
487
521
|
);
|
|
488
522
|
}
|
|
489
523
|
|
|
@@ -496,12 +530,20 @@ export function preflightAwsBootstrap(cfg, operations = {}) {
|
|
|
496
530
|
* @param {Function} write Provider writer.
|
|
497
531
|
* @returns {string} Human-readable rollback outcome with no secret material.
|
|
498
532
|
*/
|
|
499
|
-
function rollback(
|
|
533
|
+
function rollback(
|
|
534
|
+
cfg,
|
|
535
|
+
previous,
|
|
536
|
+
candidateRaw,
|
|
537
|
+
fetch,
|
|
538
|
+
write,
|
|
539
|
+
assertWithinBudget
|
|
540
|
+
) {
|
|
500
541
|
try {
|
|
501
542
|
const current = currentEntry(cfg, fetch);
|
|
502
543
|
if (current.value !== candidateRaw) {
|
|
503
544
|
return "rollback skipped because the provider changed after this publication";
|
|
504
545
|
}
|
|
546
|
+
assertWithinBudget();
|
|
505
547
|
writeProviderValue(cfg, previous.id, previous.value, write);
|
|
506
548
|
const restored = currentEntry(cfg, fetch);
|
|
507
549
|
if (restored.value !== previous.value) {
|
|
@@ -528,47 +570,56 @@ export function publishAwsBootstrap(raw, cfg, operations = {}) {
|
|
|
528
570
|
const write = operations.write ?? writeSecret;
|
|
529
571
|
const verify = operations.verify ?? verifyAwsBootstrap;
|
|
530
572
|
const candidate = validateAwsBootstrap(raw);
|
|
531
|
-
return withPublicationLock(
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
573
|
+
return withPublicationLock(
|
|
574
|
+
cfg,
|
|
575
|
+
operations,
|
|
576
|
+
(previous, assertWithinBudget) => {
|
|
577
|
+
preflightUnderLock(cfg, previous, write, assertWithinBudget);
|
|
578
|
+
|
|
579
|
+
// Verify before the write. A candidate that cannot assume one of its roles
|
|
580
|
+
// never becomes the value every new remote session receives.
|
|
581
|
+
verify(candidate);
|
|
582
|
+
assertWithinBudget();
|
|
583
|
+
|
|
584
|
+
if (candidate.raw === previous.value) {
|
|
585
|
+
return {
|
|
586
|
+
changed: false,
|
|
587
|
+
profiles: candidate.profiles.map(profile => profile.name),
|
|
588
|
+
};
|
|
589
|
+
}
|
|
544
590
|
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
591
|
+
try {
|
|
592
|
+
assertWithinBudget();
|
|
593
|
+
writeProviderValue(cfg, previous.id, candidate.raw, write);
|
|
594
|
+
const stored = currentEntry(cfg, fetch);
|
|
595
|
+
if (stored.value !== candidate.raw) {
|
|
596
|
+
throw new Error(
|
|
597
|
+
"provider read-back did not match the candidate exactly"
|
|
598
|
+
);
|
|
599
|
+
}
|
|
600
|
+
const storedCandidate = validateAwsBootstrap(stored.value);
|
|
601
|
+
verify(storedCandidate);
|
|
602
|
+
assertWithinBudget();
|
|
603
|
+
return {
|
|
604
|
+
changed: true,
|
|
605
|
+
profiles: storedCandidate.profiles.map(profile => profile.name),
|
|
606
|
+
};
|
|
607
|
+
} catch (error) {
|
|
608
|
+
const rollbackOutcome = rollback(
|
|
609
|
+
cfg,
|
|
610
|
+
previous,
|
|
611
|
+
candidate.raw,
|
|
612
|
+
fetch,
|
|
613
|
+
write,
|
|
614
|
+
assertWithinBudget
|
|
615
|
+
);
|
|
549
616
|
throw new Error(
|
|
550
|
-
|
|
617
|
+
`${BOOTSTRAP_KEY} publication failed: ${firstLine(error)}; ${rollbackOutcome}`
|
|
551
618
|
);
|
|
552
619
|
}
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
changed: true,
|
|
557
|
-
profiles: storedCandidate.profiles.map(profile => profile.name),
|
|
558
|
-
};
|
|
559
|
-
} catch (error) {
|
|
560
|
-
const rollbackOutcome = rollback(
|
|
561
|
-
cfg,
|
|
562
|
-
previous,
|
|
563
|
-
candidate.raw,
|
|
564
|
-
fetch,
|
|
565
|
-
write
|
|
566
|
-
);
|
|
567
|
-
throw new Error(
|
|
568
|
-
`${BOOTSTRAP_KEY} publication failed: ${firstLine(error)}; ${rollbackOutcome}`
|
|
569
|
-
);
|
|
570
|
-
}
|
|
571
|
-
});
|
|
620
|
+
},
|
|
621
|
+
"publication completed"
|
|
622
|
+
);
|
|
572
623
|
}
|
|
573
624
|
|
|
574
625
|
/** Read a candidate from stdin without ever placing it in argv. */
|
|
@@ -48,9 +48,9 @@ interactively and headlessly — which is why it leads. The REST tier uses:
|
|
|
48
48
|
read_sentry_token() {
|
|
49
49
|
[ -n "${SENTRY_AUTH_TOKEN:-}" ] && { echo "$SENTRY_AUTH_TOKEN"; return; }
|
|
50
50
|
#
|
|
51
|
-
# Ordered
|
|
52
|
-
#
|
|
53
|
-
#
|
|
51
|
+
# Ordered across trusted machine-managed substrates, ending at the installed
|
|
52
|
+
# package. Checkout-local paths are deliberately absent: a familiar generated
|
|
53
|
+
# destination is still repository-controlled executable code. The plugin
|
|
54
54
|
# rungs are the floor: `resolve-secret.mjs` ships beside this skill, so a rung
|
|
55
55
|
# pointing at it is reachable from anywhere the plugin itself is installed.
|
|
56
56
|
# Without one, a consumer repository that vendors none of the leading paths
|
|
@@ -59,12 +59,9 @@ read_sentry_token() {
|
|
|
59
59
|
# lookups. This LADDER is identical in every skill that resolves a credential
|
|
60
60
|
# and `credential-resolver-ladder` fails if any copy diverges. Only what
|
|
61
61
|
# happens AFTER the ladder may differ between them.
|
|
62
|
-
local
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
.opencode/skills/lisa/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
66
|
-
.codex/skills/lisa/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
67
|
-
)
|
|
62
|
+
# Execute only machine-managed plugin/package resolvers. Checkout-local
|
|
63
|
+
# candidates are repository-controlled code, not trusted merely by path.
|
|
64
|
+
local candidates=()
|
|
68
65
|
if [ -n "${CLAUDE_PLUGIN_ROOT:-}" ]; then
|
|
69
66
|
candidates+=("$CLAUDE_PLUGIN_ROOT/skills/lisa-secrets-access/scripts/resolve-secret.mjs")
|
|
70
67
|
fi
|
|
@@ -83,7 +80,7 @@ read_sentry_token() {
|
|
|
83
80
|
local via_lisa
|
|
84
81
|
via_lisa=$(node "$resolver" get SENTRY_AUTH_TOKEN 2>/dev/null) \
|
|
85
82
|
&& [ -n "$via_lisa" ] && { echo "$via_lisa"; return; }
|
|
86
|
-
|
|
83
|
+
# Empty/error means this substrate had no answer; try the next trusted one.
|
|
87
84
|
fi
|
|
88
85
|
done
|
|
89
86
|
# Name every path. A bare `return 1` sends the next reader hunting for a
|
|
@@ -86,9 +86,9 @@ read_token() {
|
|
|
86
86
|
# than "this function" is deliberate — the old wording asked for something
|
|
87
87
|
# unachievable, and an unachievable rule is one that gets quietly dropped.
|
|
88
88
|
#
|
|
89
|
-
# Ordered
|
|
90
|
-
#
|
|
91
|
-
#
|
|
89
|
+
# Ordered across trusted machine-managed substrates, ending at the installed
|
|
90
|
+
# package. Checkout-local paths are deliberately absent: a familiar generated
|
|
91
|
+
# destination is still repository-controlled executable code. The plugin
|
|
92
92
|
# rungs are the floor: `resolve-secret.mjs` ships beside this skill, so a rung
|
|
93
93
|
# pointing at it is reachable from anywhere the plugin itself is installed.
|
|
94
94
|
# Without one, a consumer repository that vendors none of the leading paths
|
|
@@ -97,12 +97,9 @@ read_token() {
|
|
|
97
97
|
# lookups. This LADDER is identical in every skill that resolves a credential
|
|
98
98
|
# and `credential-resolver-ladder` fails if any copy diverges. Only what
|
|
99
99
|
# happens AFTER the ladder may differ between them.
|
|
100
|
-
local
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
.opencode/skills/lisa/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
104
|
-
.codex/skills/lisa/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
105
|
-
)
|
|
100
|
+
# Execute only machine-managed plugin/package resolvers. Checkout-local
|
|
101
|
+
# candidates are repository-controlled code, not trusted merely by path.
|
|
102
|
+
local candidates=()
|
|
106
103
|
if [ -n "${CLAUDE_PLUGIN_ROOT:-}" ]; then
|
|
107
104
|
candidates+=("$CLAUDE_PLUGIN_ROOT/skills/lisa-secrets-access/scripts/resolve-secret.mjs")
|
|
108
105
|
fi
|
|
@@ -121,7 +118,7 @@ read_token() {
|
|
|
121
118
|
local via_lisa
|
|
122
119
|
via_lisa=$(node "$resolver" get ATLASSIAN_API_TOKEN 2>/dev/null) \
|
|
123
120
|
&& [ -n "$via_lisa" ] && { echo "$via_lisa"; return; }
|
|
124
|
-
|
|
121
|
+
# Empty/error means this substrate had no answer; try the next trusted one.
|
|
125
122
|
fi
|
|
126
123
|
done
|
|
127
124
|
# Legacy fallback: the OS keychain written by the guided flow below, for
|
|
@@ -104,17 +104,14 @@ read_linear_key() { # $1=workspace slug
|
|
|
104
104
|
# `linear-access` grew to seven, leaving `/lisa:setup:linear` unable to reach
|
|
105
105
|
# a key that `lisa-linear-access` could read from the same repository.
|
|
106
106
|
#
|
|
107
|
-
# Ordered
|
|
108
|
-
#
|
|
109
|
-
#
|
|
110
|
-
# beside this skill, so a rung
|
|
111
|
-
# plugin itself is installed.
|
|
112
|
-
local
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
.opencode/skills/lisa/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
116
|
-
.codex/skills/lisa/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
117
|
-
)
|
|
107
|
+
# Ordered across trusted machine-managed substrates, ending at the installed
|
|
108
|
+
# package. Checkout-local paths are deliberately absent: a familiar generated
|
|
109
|
+
# destination is still repository-controlled executable code. The plugin
|
|
110
|
+
# rungs are the floor: `resolve-secret.mjs` ships beside this skill, so a rung
|
|
111
|
+
# pointing at it is reachable from anywhere the plugin itself is installed.
|
|
112
|
+
# Execute only machine-managed plugin/package resolvers. Checkout-local
|
|
113
|
+
# candidates are repository-controlled code, not trusted merely by path.
|
|
114
|
+
local candidates=()
|
|
118
115
|
if [ -n "${CLAUDE_PLUGIN_ROOT:-}" ]; then
|
|
119
116
|
candidates+=("$CLAUDE_PLUGIN_ROOT/skills/lisa-secrets-access/scripts/resolve-secret.mjs")
|
|
120
117
|
fi
|
|
@@ -133,7 +130,7 @@ read_linear_key() { # $1=workspace slug
|
|
|
133
130
|
local via_lisa
|
|
134
131
|
via_lisa=$(node "$resolver" get LINEAR_API_KEY 2>/dev/null) \
|
|
135
132
|
&& [ -n "$via_lisa" ] && { echo "$via_lisa"; return; }
|
|
136
|
-
|
|
133
|
+
# Empty/error means this substrate had no answer; try the next trusted one.
|
|
137
134
|
fi
|
|
138
135
|
done
|
|
139
136
|
# Legacy fallback: the OS keychain written by the guided flow below, for
|
|
@@ -173,9 +173,9 @@ read_notion_token() {
|
|
|
173
173
|
# than "this function" is deliberate — the old wording asked for something
|
|
174
174
|
# unachievable, and an unachievable rule is one that gets quietly dropped.
|
|
175
175
|
#
|
|
176
|
-
# Ordered
|
|
177
|
-
#
|
|
178
|
-
#
|
|
176
|
+
# Ordered across trusted machine-managed substrates, ending at the installed
|
|
177
|
+
# package. Checkout-local paths are deliberately absent: a familiar generated
|
|
178
|
+
# destination is still repository-controlled executable code. The plugin
|
|
179
179
|
# rungs are the floor: `resolve-secret.mjs` ships beside this skill, so a rung
|
|
180
180
|
# pointing at it is reachable from anywhere the plugin itself is installed.
|
|
181
181
|
# Without one, a consumer repository that vendors none of the leading paths
|
|
@@ -184,12 +184,9 @@ read_notion_token() {
|
|
|
184
184
|
# lookups. This LADDER is identical in every skill that resolves a credential
|
|
185
185
|
# and `credential-resolver-ladder` fails if any copy diverges. Only what
|
|
186
186
|
# happens AFTER the ladder may differ between them.
|
|
187
|
-
local
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
.opencode/skills/lisa/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
191
|
-
.codex/skills/lisa/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
192
|
-
)
|
|
187
|
+
# Execute only machine-managed plugin/package resolvers. Checkout-local
|
|
188
|
+
# candidates are repository-controlled code, not trusted merely by path.
|
|
189
|
+
local candidates=()
|
|
193
190
|
if [ -n "${CLAUDE_PLUGIN_ROOT:-}" ]; then
|
|
194
191
|
candidates+=("$CLAUDE_PLUGIN_ROOT/skills/lisa-secrets-access/scripts/resolve-secret.mjs")
|
|
195
192
|
fi
|
|
@@ -208,7 +205,7 @@ read_notion_token() {
|
|
|
208
205
|
local via_lisa
|
|
209
206
|
via_lisa=$(node "$resolver" get NOTION_API_TOKEN 2>/dev/null) \
|
|
210
207
|
&& [ -n "$via_lisa" ] && { echo "$via_lisa"; return; }
|
|
211
|
-
|
|
208
|
+
# Empty/error means this substrate had no answer; try the next trusted one.
|
|
212
209
|
fi
|
|
213
210
|
done
|
|
214
211
|
# Legacy fallback: the OS keychain written by the guided flow below, for
|
|
@@ -64,13 +64,18 @@ The lock remains held through rollback and its deletion is verified before the
|
|
|
64
64
|
command reports success:
|
|
65
65
|
|
|
66
66
|
```bash
|
|
67
|
-
aws
|
|
68
|
-
--secret-id
|
|
67
|
+
aws secretsmanager get-secret-value \
|
|
68
|
+
--secret-id <selected-secret-name> \
|
|
69
69
|
--query SecretString \
|
|
70
70
|
--output text \
|
|
71
71
|
| node .claude/skills/lisa-secrets-access/scripts/publish-aws-bootstrap.mjs publish
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
+
Use the same secret name passed to `--secret-name`; the default is
|
|
75
|
+
`remote-agent-credentials`. Add `--profile <source-profile>` only when the
|
|
76
|
+
operator's ambient AWS identity cannot read the emission and the project names
|
|
77
|
+
a source profile. A named `shared` profile is not otherwise required.
|
|
78
|
+
|
|
74
79
|
Resolve the script from the installed runtime or `node_modules` when the
|
|
75
80
|
`.claude/skills` copy is not present. Never print or place the candidate in an
|
|
76
81
|
argument or temporary file. A CDK deployment followed later by a human copy is
|
|
@@ -97,9 +97,14 @@ A surface that **re-runs this script when a container resumes** — Codex Cloud
|
|
|
97
97
|
A surface that **skips this script whenever a filesystem cache exists** — Claude Code web — must not. Materializing here would write the values once and then never refresh them, so a credential rotated on Tuesday would still be serving Monday's value until the cache expired days later. Those surfaces materialize from a session-start hook instead, which runs every session including a resumed one:
|
|
98
98
|
|
|
99
99
|
```sh
|
|
100
|
-
bash scripts/lisa-remote-env/session-start.sh #
|
|
100
|
+
bash "$CLAUDE_PROJECT_DIR/scripts/lisa-remote-env/session-start.sh" # project-scoped absolute hook
|
|
101
101
|
```
|
|
102
102
|
|
|
103
|
+
The installer also registers a user-scoped hook using the checkout's resolved
|
|
104
|
+
absolute path. If invoking this asset by hand, either use that absolute path or
|
|
105
|
+
change to the repository root first; a bare checkout-relative command is not a
|
|
106
|
+
portable session-start configuration.
|
|
107
|
+
|
|
103
108
|
The selection comes from the surface's `materializeAt` capability in `lisa-secrets-access`, not from its name, so adding a surface does not mean editing a branch. The hook is committed to the repository, so it also fires on a developer's machine — it exits `0` immediately there rather than failing, because a correct local session must not look broken.
|
|
104
109
|
|
|
105
110
|
## Detect before you provision
|
|
@@ -46,8 +46,27 @@ here="$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd)"
|
|
|
46
46
|
# SessionStart hosts are fail-open, so they surface that result and still allow
|
|
47
47
|
# the agent session to continue.
|
|
48
48
|
bash "${here}/setup.sh" --phase=toolchain "$@"
|
|
49
|
+
|
|
50
|
+
# The toolchain child cannot export into this parent shell. Its durable output
|
|
51
|
+
# is linked into ~/.local/bin, so make that directory visible before the next
|
|
52
|
+
# child tries to execute the provider CLI it just installed.
|
|
53
|
+
case ":$PATH:" in
|
|
54
|
+
*":$HOME/.local/bin:"*) ;;
|
|
55
|
+
*) PATH="$HOME/.local/bin:$PATH"; export PATH ;;
|
|
56
|
+
esac
|
|
57
|
+
|
|
49
58
|
bash "${here}/setup.sh" --phase=secrets "$@"
|
|
50
59
|
|
|
60
|
+
# Materialization writes a Lisa-owned block into .profile that sources the
|
|
61
|
+
# generated environment and removes ambient AWS credential poison. The project
|
|
62
|
+
# hook is another non-login child, so load that block here and let the child
|
|
63
|
+
# inherit the exact environment materialization just produced.
|
|
64
|
+
if [ -r "$HOME/.profile" ]; then
|
|
65
|
+
# The materializer owns this runtime path.
|
|
66
|
+
# shellcheck disable=SC1090
|
|
67
|
+
. "$HOME/.profile"
|
|
68
|
+
fi
|
|
69
|
+
|
|
51
70
|
# A project hook is part of the remote toolchain contract too. It covers tools
|
|
52
71
|
# that cannot be expressed by the pinned manifest, so skipping it on a cached
|
|
53
72
|
# session can leave fresh credentials with no client capable of using them.
|
|
@@ -132,6 +132,7 @@ for candidate in \
|
|
|
132
132
|
".claude/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs" \
|
|
133
133
|
".agents/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs" \
|
|
134
134
|
".codex/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs" \
|
|
135
|
+
".opencode/skills/lisa/lisa-setup-remote-env/scripts/setup-remote-env.mjs" \
|
|
135
136
|
"plugins/lisa/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs" \
|
|
136
137
|
"node_modules/@codyswann/lisa/plugins/lisa/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs"; do
|
|
137
138
|
if [ -f "$candidate" ]; then
|
package/plugins/lisa/.codex-plugin/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs
CHANGED
|
@@ -51,7 +51,10 @@ import { pathDirs } from "../../lisa-setup-workstation/scripts/catalogue.mjs";
|
|
|
51
51
|
|
|
52
52
|
import { assertPinned, extractVersion, planToolchain } from "./toolchain.mjs";
|
|
53
53
|
|
|
54
|
-
import {
|
|
54
|
+
import {
|
|
55
|
+
boundedChildOutput,
|
|
56
|
+
SETUP_OPERATION_BUDGET_MS,
|
|
57
|
+
} from "../../lisa-setup-workstation/scripts/bounded-child.mjs";
|
|
55
58
|
|
|
56
59
|
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
57
60
|
|
|
@@ -173,12 +176,14 @@ function installReleaseZip(tool, binDir) {
|
|
|
173
176
|
const archive = join(temporary, "download.zip");
|
|
174
177
|
boundedChildOutput("curl", ["-fsSL", tool.url, "-o", archive], {
|
|
175
178
|
stdio: "inherit",
|
|
179
|
+
timeout: SETUP_OPERATION_BUDGET_MS,
|
|
176
180
|
});
|
|
177
181
|
// Verify before unpacking, not after. An unexpected archive must fail
|
|
178
182
|
// before any of its contents reach a directory that is on PATH.
|
|
179
183
|
verifyChecksum(archive, tool.sha256, tool.name);
|
|
180
184
|
boundedChildOutput("unzip", ["-q", "-o", archive, "-d", temporary], {
|
|
181
185
|
stdio: "inherit",
|
|
186
|
+
timeout: SETUP_OPERATION_BUDGET_MS,
|
|
182
187
|
});
|
|
183
188
|
const binary = join(temporary, tool.binary ?? tool.name);
|
|
184
189
|
boundedChildOutput(
|
|
@@ -186,6 +191,7 @@ function installReleaseZip(tool, binDir) {
|
|
|
186
191
|
["-m", "0755", binary, join(binDir, tool.name)],
|
|
187
192
|
{
|
|
188
193
|
stdio: "inherit",
|
|
194
|
+
timeout: SETUP_OPERATION_BUDGET_MS,
|
|
189
195
|
}
|
|
190
196
|
);
|
|
191
197
|
} finally {
|
|
@@ -210,10 +216,12 @@ function installReleaseTar(tool, binDir) {
|
|
|
210
216
|
const archive = join(temporary, "download.tar.gz");
|
|
211
217
|
boundedChildOutput("curl", ["-fsSL", tool.url, "-o", archive], {
|
|
212
218
|
stdio: "inherit",
|
|
219
|
+
timeout: SETUP_OPERATION_BUDGET_MS,
|
|
213
220
|
});
|
|
214
221
|
verifyChecksum(archive, tool.sha256, tool.name);
|
|
215
222
|
boundedChildOutput("tar", ["-xzf", archive, "-C", temporary], {
|
|
216
223
|
stdio: "inherit",
|
|
224
|
+
timeout: SETUP_OPERATION_BUDGET_MS,
|
|
217
225
|
});
|
|
218
226
|
// Release tarballs usually nest under a versioned directory, so `binary` is
|
|
219
227
|
// a path within the archive rather than a bare name.
|
|
@@ -223,6 +231,7 @@ function installReleaseTar(tool, binDir) {
|
|
|
223
231
|
["-m", "0755", binary, join(binDir, tool.name)],
|
|
224
232
|
{
|
|
225
233
|
stdio: "inherit",
|
|
234
|
+
timeout: SETUP_OPERATION_BUDGET_MS,
|
|
226
235
|
}
|
|
227
236
|
);
|
|
228
237
|
} finally {
|
|
@@ -272,6 +281,7 @@ function installReleaseTree(tool, binDir) {
|
|
|
272
281
|
const archive = join(temporary, "download.archive");
|
|
273
282
|
boundedChildOutput("curl", ["-fsSL", tool.url, "-o", archive], {
|
|
274
283
|
stdio: "inherit",
|
|
284
|
+
timeout: SETUP_OPERATION_BUDGET_MS,
|
|
275
285
|
});
|
|
276
286
|
// Verify before unpacking, as everywhere else here: an unexpected archive
|
|
277
287
|
// must fail before any of its contents reach the filesystem.
|
|
@@ -285,10 +295,12 @@ function installReleaseTree(tool, binDir) {
|
|
|
285
295
|
if (tool.url.endsWith(".zip")) {
|
|
286
296
|
boundedChildOutput("unzip", ["-q", "-o", archive, "-d", prefix], {
|
|
287
297
|
stdio: "inherit",
|
|
298
|
+
timeout: SETUP_OPERATION_BUDGET_MS,
|
|
288
299
|
});
|
|
289
300
|
} else {
|
|
290
301
|
boundedChildOutput("tar", ["-xzf", archive, "-C", prefix], {
|
|
291
302
|
stdio: "inherit",
|
|
303
|
+
timeout: SETUP_OPERATION_BUDGET_MS,
|
|
292
304
|
});
|
|
293
305
|
}
|
|
294
306
|
|
|
@@ -342,6 +354,7 @@ function installReleaseBinary(tool, binDir) {
|
|
|
342
354
|
const artifact = join(temporary, tool.name);
|
|
343
355
|
boundedChildOutput("curl", ["-fsSL", tool.url, "-o", artifact], {
|
|
344
356
|
stdio: "inherit",
|
|
357
|
+
timeout: SETUP_OPERATION_BUDGET_MS,
|
|
345
358
|
});
|
|
346
359
|
// Verify before it reaches a directory on PATH. For this kind that ordering
|
|
347
360
|
// matters more than for the archives: the downloaded file is directly
|
|
@@ -353,6 +366,7 @@ function installReleaseBinary(tool, binDir) {
|
|
|
353
366
|
["-m", "0755", artifact, join(binDir, tool.name)],
|
|
354
367
|
{
|
|
355
368
|
stdio: "inherit",
|
|
369
|
+
timeout: SETUP_OPERATION_BUDGET_MS,
|
|
356
370
|
}
|
|
357
371
|
);
|
|
358
372
|
} finally {
|
|
@@ -370,6 +384,7 @@ function installNpmGlobal(tool) {
|
|
|
370
384
|
["install", "--global", `${tool.package}@${tool.version}`],
|
|
371
385
|
{
|
|
372
386
|
stdio: "inherit",
|
|
387
|
+
timeout: SETUP_OPERATION_BUDGET_MS,
|
|
373
388
|
}
|
|
374
389
|
);
|
|
375
390
|
}
|
|
@@ -509,7 +524,10 @@ function runHook(hook, dryRun) {
|
|
|
509
524
|
console.log(`\nProject hook: ${hook}`);
|
|
510
525
|
if (dryRun) return;
|
|
511
526
|
chmodSync(path, 0o755);
|
|
512
|
-
boundedChildOutput("bash", [path], {
|
|
527
|
+
boundedChildOutput("bash", [path], {
|
|
528
|
+
stdio: "inherit",
|
|
529
|
+
timeout: SETUP_OPERATION_BUDGET_MS,
|
|
530
|
+
});
|
|
513
531
|
}
|
|
514
532
|
|
|
515
533
|
/** Phases this runner can execute, in the order they must happen. */
|
|
@@ -789,7 +807,10 @@ export function installUserSessionHook(repoRoot, options = {}) {
|
|
|
789
807
|
|
|
790
808
|
const dir = join(home, ".claude");
|
|
791
809
|
const settingsPath = join(dir, "settings.json");
|
|
792
|
-
|
|
810
|
+
// Settings stores shell source, so the absolute path still needs quoting.
|
|
811
|
+
// JSON string syntax is accepted by the shell for ordinary path text and
|
|
812
|
+
// safely escapes spaces, quotes, dollars and backticks.
|
|
813
|
+
const command = `bash ${JSON.stringify(script)}`;
|
|
793
814
|
|
|
794
815
|
let settings = {};
|
|
795
816
|
if (exists(settingsPath)) {
|
|
@@ -1506,7 +1527,7 @@ async function main() {
|
|
|
1506
1527
|
boundedChildOutput(
|
|
1507
1528
|
"node",
|
|
1508
1529
|
dryRun ? [materialize, "--dry-run"] : [materialize],
|
|
1509
|
-
{ stdio: "inherit" }
|
|
1530
|
+
{ stdio: "inherit", timeout: SETUP_OPERATION_BUDGET_MS }
|
|
1510
1531
|
);
|
|
1511
1532
|
} catch (err) {
|
|
1512
1533
|
if (!retried) throw err;
|
|
@@ -83,6 +83,15 @@ import { execFileSync, spawnSync } from "node:child_process";
|
|
|
83
83
|
*/
|
|
84
84
|
export const CHILD_BUDGET_MS = 30_000;
|
|
85
85
|
|
|
86
|
+
/**
|
|
87
|
+
* Deadline for setup operations that legitimately include downloads, package
|
|
88
|
+
* installation, secret-provider calls, or a project-declared hook.
|
|
89
|
+
*
|
|
90
|
+
* Kept separate from {@link CHILD_BUDGET_MS}: probes should still fail quickly,
|
|
91
|
+
* while a cold network install must not be killed by the probe budget.
|
|
92
|
+
*/
|
|
93
|
+
export const SETUP_OPERATION_BUDGET_MS = 10 * 60_000;
|
|
94
|
+
|
|
86
95
|
/**
|
|
87
96
|
* Whether this value is a child that was killed at its deadline.
|
|
88
97
|
*
|