@codyswann/lisa 2.332.5 → 2.333.1

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.
Files changed (78) hide show
  1. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  2. package/dist/core/upstream-evidence-manifest.js +6 -4
  3. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  4. package/package.json +1 -1
  5. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  6. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  7. package/plugins/lisa/.codex-plugin/skills/lisa-parity-sentry-sdk-setup/SKILL.md +2 -2
  8. package/plugins/lisa/.codex-plugin/skills/lisa-parity-sentry-seer/SKILL.md +2 -2
  9. package/plugins/lisa/.codex-plugin/skills/lisa-secrets-access/scripts/aws-bootstrap.mjs +154 -9
  10. package/plugins/lisa/.codex-plugin/skills/lisa-secrets-access/scripts/materialize-secrets.mjs +93 -2
  11. package/plugins/lisa/skills/lisa-parity-sentry-sdk-setup/SKILL.md +2 -2
  12. package/plugins/lisa/skills/lisa-parity-sentry-seer/SKILL.md +2 -2
  13. package/plugins/lisa/skills/lisa-secrets-access/scripts/aws-bootstrap.mjs +154 -9
  14. package/plugins/lisa/skills/lisa-secrets-access/scripts/materialize-secrets.mjs +93 -2
  15. package/plugins/lisa-agy/plugin.json +1 -1
  16. package/plugins/lisa-agy/skills/lisa-parity-sentry-sdk-setup/SKILL.md +2 -2
  17. package/plugins/lisa-agy/skills/lisa-parity-sentry-seer/SKILL.md +2 -2
  18. package/plugins/lisa-agy/skills/lisa-secrets-access/scripts/aws-bootstrap.mjs +154 -9
  19. package/plugins/lisa-agy/skills/lisa-secrets-access/scripts/materialize-secrets.mjs +93 -2
  20. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  21. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  22. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  23. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  24. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  25. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  26. package/plugins/lisa-copilot/skills/lisa-parity-sentry-sdk-setup/SKILL.md +2 -2
  27. package/plugins/lisa-copilot/skills/lisa-parity-sentry-seer/SKILL.md +2 -2
  28. package/plugins/lisa-copilot/skills/lisa-secrets-access/scripts/aws-bootstrap.mjs +154 -9
  29. package/plugins/lisa-copilot/skills/lisa-secrets-access/scripts/materialize-secrets.mjs +93 -2
  30. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  31. package/plugins/lisa-cursor/skills/lisa-parity-sentry-sdk-setup/SKILL.md +2 -2
  32. package/plugins/lisa-cursor/skills/lisa-parity-sentry-seer/SKILL.md +2 -2
  33. package/plugins/lisa-cursor/skills/lisa-secrets-access/scripts/aws-bootstrap.mjs +154 -9
  34. package/plugins/lisa-cursor/skills/lisa-secrets-access/scripts/materialize-secrets.mjs +93 -2
  35. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  36. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  37. package/plugins/lisa-expo-agy/plugin.json +1 -1
  38. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  39. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  40. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  41. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  42. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  43. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  44. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  45. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  46. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  47. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  48. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  49. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  50. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  51. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  52. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  53. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  54. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  55. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  56. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  57. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  58. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  59. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  60. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  61. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  62. package/plugins/lisa-rails-agy/plugin.json +1 -1
  63. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  64. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  65. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  66. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  67. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  68. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  69. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  70. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  71. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  72. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  73. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  74. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  75. package/plugins/src/base/skills/lisa-parity-sentry-sdk-setup/SKILL.md +2 -2
  76. package/plugins/src/base/skills/lisa-parity-sentry-seer/SKILL.md +2 -2
  77. package/plugins/src/base/skills/lisa-secrets-access/scripts/aws-bootstrap.mjs +154 -9
  78. package/plugins/src/base/skills/lisa-secrets-access/scripts/materialize-secrets.mjs +93 -2
@@ -31,7 +31,12 @@ import {
31
31
  import { homedir } from "node:os";
32
32
  import { join } from "node:path";
33
33
 
34
- import { deriveAwsEnvironment } from "./aws-bootstrap.mjs";
34
+ import {
35
+ BOOTSTRAP_KEY,
36
+ deriveAwsEnvironment,
37
+ parseBootstrap,
38
+ renderAwsProfiles,
39
+ } from "./aws-bootstrap.mjs";
35
40
  import { renderEnv, renderNotes } from "./envfile.mjs";
36
41
  import { fetchAll } from "./providers.mjs";
37
42
  import { materializedPaths, readConfig } from "./surfaces.mjs";
@@ -68,6 +73,15 @@ const PROFILE_MARKER = "# >>> lisa secrets (managed) >>>";
68
73
  /** Closes the managed block. */
69
74
  const PROFILE_END = "# <<< lisa secrets (managed) <<<";
70
75
 
76
+ /**
77
+ * Identifies an `~/.aws` file as one this wrote, and may therefore replace.
78
+ *
79
+ * `#` is a comment in the AWS shared-config format, so this is inert to every
80
+ * consumer while still being the thing that distinguishes "our file, refresh
81
+ * it" from "someone else's file, leave it alone".
82
+ */
83
+ const MANAGED_MARKER = "# managed by lisa-secrets-access";
84
+
71
85
  /**
72
86
  * Make every shell in this container load the materialized secrets.
73
87
  *
@@ -95,6 +109,14 @@ export function installProfileSourcing(valuesFile, options = {}) {
95
109
 
96
110
  const block = [
97
111
  PROFILE_MARKER,
112
+ // Unset BEFORE sourcing. A cloud container injects its own AWS key pair,
113
+ // and environment credentials outrank both ~/.aws profiles and AWS_PROFILE
114
+ // — so leaving them set means the session ignores whichever environment it
115
+ // selected and runs as whatever the host injected. That is how a perfectly
116
+ // valid credential produced InvalidClientTokenId for a day. Removing the
117
+ // poison beats out-shouting it, and it is what lets `--profile agent-dev`
118
+ // behave here exactly as it does on a developer's machine.
119
+ `unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN`,
98
120
  `if [ -f "${valuesFile}" ]; then`,
99
121
  ` set -a`,
100
122
  ` . "${valuesFile}"`,
@@ -126,6 +148,61 @@ export function installProfileSourcing(valuesFile, options = {}) {
126
148
  return updated;
127
149
  }
128
150
 
151
+ /**
152
+ * Write `~/.aws/credentials` and `~/.aws/config` from the bootstrap bundle.
153
+ *
154
+ * Both at 0600 inside a 0700 directory, matching how the materialized secrets
155
+ * themselves are protected — the credentials file holds the source key pair.
156
+ * @param {object|null} bundle Parsed bootstrap bundle.
157
+ * @param {object} [options] Home directory and file seams, for tests.
158
+ * @returns {string[]} The profile names written.
159
+ */
160
+ export function installAwsProfiles(bundle, options = {}) {
161
+ const {
162
+ home = process.env.HOME || homedir(),
163
+ mkdir = mkdirSync,
164
+ write = writeFileSync,
165
+ read = readFileSync,
166
+ exists = existsSync,
167
+ chmod = chmodSync,
168
+ } = options;
169
+
170
+ const rendered = renderAwsProfiles(bundle);
171
+ if (!rendered) return [];
172
+
173
+ const dir = join(home, ".aws");
174
+
175
+ // Never overwrite an ~/.aws this did not write.
176
+ //
177
+ // These are whole-file writes, so a pre-existing credentials file — a
178
+ // developer's own profiles, or something another tool set up — would be
179
+ // destroyed rather than merged. This only runs on a surface allowed to write
180
+ // secrets to disk (a disposable container), but "usually disposable" is not a
181
+ // reason to be able to delete someone's credentials. The marker makes our own
182
+ // file re-writable while anything else is left alone and reported.
183
+ for (const name of ["credentials", "config"]) {
184
+ const file = join(dir, name);
185
+ if (exists(file) && !String(read(file, "utf8")).includes(MANAGED_MARKER)) {
186
+ return [];
187
+ }
188
+ }
189
+
190
+ mkdir(dir, { recursive: true, mode: 0o700 });
191
+ chmod(dir, 0o700);
192
+ write(
193
+ join(dir, "credentials"),
194
+ `${MANAGED_MARKER}\n${rendered.credentials}`,
195
+ {
196
+ mode: 0o600,
197
+ }
198
+ );
199
+ write(join(dir, "config"), `${MANAGED_MARKER}\n${rendered.config}`, {
200
+ mode: 0o600,
201
+ });
202
+
203
+ return rendered.profiles;
204
+ }
205
+
129
206
  export function materialize(cfg = readConfig()) {
130
207
  if (!cfg.capabilities.mayWriteValues) {
131
208
  throw new Error(
@@ -170,7 +247,21 @@ export function materialize(cfg = readConfig()) {
170
247
  // materialized" and "the credential is usable" the same statement.
171
248
  const sourced = installProfileSourcing(valuesFile);
172
249
 
173
- return { count: selected.size, derived: derived.size, dir, sourced };
250
+ // The environments live in separate AWS accounts, reached by assuming a role
251
+ // per environment. Without these files `--profile agent-dev` fails with
252
+ // "profile not found" and everything silently falls back to the bootstrap
253
+ // identity, which can assume roles and do nothing else.
254
+ const profiles = installAwsProfiles(
255
+ parseBootstrap(selected.get(BOOTSTRAP_KEY)?.value)
256
+ );
257
+
258
+ return {
259
+ count: selected.size,
260
+ derived: derived.size,
261
+ dir,
262
+ sourced,
263
+ profiles,
264
+ };
174
265
  }
175
266
 
176
267
  function main() {