@codyswann/lisa 2.331.0 → 2.331.2
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/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +5 -4
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/package.json +1 -1
- 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-secrets-access/scripts/surfaces.mjs +22 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +26 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-setup-workstation/SKILL.md +4 -3
- package/plugins/lisa/.codex-plugin/skills/lisa-setup-workstation/scripts/catalogue.mjs +7 -5
- package/plugins/lisa/skills/lisa-secrets-access/scripts/surfaces.mjs +22 -1
- package/plugins/lisa/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +26 -2
- package/plugins/lisa/skills/lisa-setup-workstation/SKILL.md +4 -3
- package/plugins/lisa/skills/lisa-setup-workstation/scripts/catalogue.mjs +7 -5
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/lisa-secrets-access/scripts/surfaces.mjs +22 -1
- package/plugins/lisa-agy/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +26 -2
- package/plugins/lisa-agy/skills/lisa-setup-workstation/SKILL.md +4 -3
- package/plugins/lisa-agy/skills/lisa-setup-workstation/scripts/catalogue.mjs +7 -5
- 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-secrets-access/scripts/surfaces.mjs +22 -1
- package/plugins/lisa-copilot/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +26 -2
- package/plugins/lisa-copilot/skills/lisa-setup-workstation/SKILL.md +4 -3
- package/plugins/lisa-copilot/skills/lisa-setup-workstation/scripts/catalogue.mjs +7 -5
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/skills/lisa-secrets-access/scripts/surfaces.mjs +22 -1
- package/plugins/lisa-cursor/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +26 -2
- package/plugins/lisa-cursor/skills/lisa-setup-workstation/SKILL.md +4 -3
- package/plugins/lisa-cursor/skills/lisa-setup-workstation/scripts/catalogue.mjs +7 -5
- 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-secrets-access/scripts/surfaces.mjs +22 -1
- package/plugins/src/base/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +26 -2
- package/plugins/src/base/skills/lisa-setup-workstation/SKILL.md +4 -3
- package/plugins/src/base/skills/lisa-setup-workstation/scripts/catalogue.mjs +7 -5
package/package.json
CHANGED
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
"brace-expansion": ">=5.0.9"
|
|
116
116
|
},
|
|
117
117
|
"name": "@codyswann/lisa",
|
|
118
|
-
"version": "2.331.
|
|
118
|
+
"version": "2.331.2",
|
|
119
119
|
"description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
|
|
120
120
|
"main": "dist/index.js",
|
|
121
121
|
"exports": {
|
|
@@ -56,7 +56,28 @@ export const SURFACES = {
|
|
|
56
56
|
"claude-web": {
|
|
57
57
|
materialized: true,
|
|
58
58
|
mayWriteValues: true,
|
|
59
|
-
|
|
59
|
+
// BOTH, and the two cover disjoint failures rather than duplicating work.
|
|
60
|
+
//
|
|
61
|
+
// The hook alone was the original design, for a real reason: this surface
|
|
62
|
+
// skips its setup script whenever a cached environment exists, so
|
|
63
|
+
// materializing only there would write values once and never refresh them.
|
|
64
|
+
//
|
|
65
|
+
// What that missed is that the hook is PROJECT-scoped — it lives in a
|
|
66
|
+
// repository's `.claude/settings.json` and only loads when Claude Code's
|
|
67
|
+
// project directory is that repository. A cloud environment configured with
|
|
68
|
+
// more than one repository starts in their parent:
|
|
69
|
+
//
|
|
70
|
+
// HOME=/root PWD=/home/user
|
|
71
|
+
// /home/user/backend /home/user/infrastructure
|
|
72
|
+
//
|
|
73
|
+
// `/home/user` is not a project root, so no settings load, no hook
|
|
74
|
+
// registers, and nothing materializes at all. Verified in a real session.
|
|
75
|
+
//
|
|
76
|
+
// So the setup run is the FLOOR — a fresh environment has its secrets even
|
|
77
|
+
// where the hook cannot fire — and the hook is the REFRESH, picking up
|
|
78
|
+
// rotation on resumed sessions that skip setup. A stale secret is
|
|
79
|
+
// recoverable; an absent one means the environment does not work.
|
|
80
|
+
materializeAt: "both",
|
|
60
81
|
},
|
|
61
82
|
};
|
|
62
83
|
|
package/plugins/lisa/.codex-plugin/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs
CHANGED
|
@@ -736,7 +736,7 @@ export function selectPhases(requested, materializeAt) {
|
|
|
736
736
|
`unknown --phase "${requested}". Known: ${PHASES.join(", ")}.`
|
|
737
737
|
);
|
|
738
738
|
}
|
|
739
|
-
if (requested === "secrets" && materializeAt
|
|
739
|
+
if (requested === "secrets" && !materializesAtSessionStart(materializeAt)) {
|
|
740
740
|
// Not an error: the hook is committed to the repository and runs on every
|
|
741
741
|
// surface the project is ever checked out on. Refusing loudly would make
|
|
742
742
|
// a correct local session look broken every time it started.
|
|
@@ -745,10 +745,34 @@ export function selectPhases(requested, materializeAt) {
|
|
|
745
745
|
return [requested];
|
|
746
746
|
}
|
|
747
747
|
return PHASES.filter(
|
|
748
|
-
phase => phase !== "secrets" || materializeAt
|
|
748
|
+
phase => phase !== "secrets" || materializesAtSetup(materializeAt)
|
|
749
749
|
);
|
|
750
750
|
}
|
|
751
751
|
|
|
752
|
+
/**
|
|
753
|
+
* Whether the setup run itself should materialize.
|
|
754
|
+
*
|
|
755
|
+
* `"both"` means the surface materializes in the setup run AND from the
|
|
756
|
+
* session-start hook, because on that surface either one alone has a hole: the
|
|
757
|
+
* setup run is skipped when a cached environment is reused, and the hook cannot
|
|
758
|
+
* fire when Claude Code's project directory is not the repository — which is
|
|
759
|
+
* every cloud environment configured with more than one repo.
|
|
760
|
+
* @param {string|null} materializeAt Surface capability.
|
|
761
|
+
* @returns {boolean} Whether to materialize during setup.
|
|
762
|
+
*/
|
|
763
|
+
export function materializesAtSetup(materializeAt) {
|
|
764
|
+
return materializeAt === "setup" || materializeAt === "both";
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
/**
|
|
768
|
+
* Whether the committed session-start hook should materialize.
|
|
769
|
+
* @param {string|null} materializeAt Surface capability.
|
|
770
|
+
* @returns {boolean} Whether the hook does the work.
|
|
771
|
+
*/
|
|
772
|
+
export function materializesAtSessionStart(materializeAt) {
|
|
773
|
+
return materializeAt === "session-start" || materializeAt === "both";
|
|
774
|
+
}
|
|
775
|
+
|
|
752
776
|
/**
|
|
753
777
|
* Read the surface the resolver detects, without duplicating its rules.
|
|
754
778
|
*
|
|
@@ -137,6 +137,7 @@ than stopping.
|
|
|
137
137
|
- **Install a credential manager you did not pick.**
|
|
138
138
|
- **Reinstall over a tool that is already there**, whatever installed it.
|
|
139
139
|
- **Install anything without `--install`.**
|
|
140
|
-
- **Install
|
|
141
|
-
with a pointer, because "not installed" and "cannot be installed by
|
|
142
|
-
different answers to the operator.
|
|
140
|
+
- **Install a tool whose vendor publishes no headless installer.** Such an entry is
|
|
141
|
+
reported as manual with a pointer, because "not installed" and "cannot be installed by
|
|
142
|
+
this tool" are different answers to the operator. No agent is currently in that state —
|
|
143
|
+
Antigravity was listed there in error and does publish a bootstrapper.
|
|
@@ -66,11 +66,13 @@ export const AGENTS = [
|
|
|
66
66
|
{
|
|
67
67
|
name: "agy",
|
|
68
68
|
label: "Antigravity",
|
|
69
|
-
kind: "
|
|
70
|
-
//
|
|
71
|
-
//
|
|
72
|
-
//
|
|
73
|
-
|
|
69
|
+
kind: "vendor-script",
|
|
70
|
+
// Google does publish a headless bootstrapper; this entry previously said
|
|
71
|
+
// otherwise and reported the agent as uninstallable. Confirmed live —
|
|
72
|
+
// `content-type: application/x-sh`, and the payload is a bash script that
|
|
73
|
+
// downloads and verifies the flat native build.
|
|
74
|
+
script: "https://antigravity.google/cli/install.sh",
|
|
75
|
+
selfUpdates: true,
|
|
74
76
|
},
|
|
75
77
|
{
|
|
76
78
|
name: "copilot",
|
|
@@ -56,7 +56,28 @@ export const SURFACES = {
|
|
|
56
56
|
"claude-web": {
|
|
57
57
|
materialized: true,
|
|
58
58
|
mayWriteValues: true,
|
|
59
|
-
|
|
59
|
+
// BOTH, and the two cover disjoint failures rather than duplicating work.
|
|
60
|
+
//
|
|
61
|
+
// The hook alone was the original design, for a real reason: this surface
|
|
62
|
+
// skips its setup script whenever a cached environment exists, so
|
|
63
|
+
// materializing only there would write values once and never refresh them.
|
|
64
|
+
//
|
|
65
|
+
// What that missed is that the hook is PROJECT-scoped — it lives in a
|
|
66
|
+
// repository's `.claude/settings.json` and only loads when Claude Code's
|
|
67
|
+
// project directory is that repository. A cloud environment configured with
|
|
68
|
+
// more than one repository starts in their parent:
|
|
69
|
+
//
|
|
70
|
+
// HOME=/root PWD=/home/user
|
|
71
|
+
// /home/user/backend /home/user/infrastructure
|
|
72
|
+
//
|
|
73
|
+
// `/home/user` is not a project root, so no settings load, no hook
|
|
74
|
+
// registers, and nothing materializes at all. Verified in a real session.
|
|
75
|
+
//
|
|
76
|
+
// So the setup run is the FLOOR — a fresh environment has its secrets even
|
|
77
|
+
// where the hook cannot fire — and the hook is the REFRESH, picking up
|
|
78
|
+
// rotation on resumed sessions that skip setup. A stale secret is
|
|
79
|
+
// recoverable; an absent one means the environment does not work.
|
|
80
|
+
materializeAt: "both",
|
|
60
81
|
},
|
|
61
82
|
};
|
|
62
83
|
|
|
@@ -736,7 +736,7 @@ export function selectPhases(requested, materializeAt) {
|
|
|
736
736
|
`unknown --phase "${requested}". Known: ${PHASES.join(", ")}.`
|
|
737
737
|
);
|
|
738
738
|
}
|
|
739
|
-
if (requested === "secrets" && materializeAt
|
|
739
|
+
if (requested === "secrets" && !materializesAtSessionStart(materializeAt)) {
|
|
740
740
|
// Not an error: the hook is committed to the repository and runs on every
|
|
741
741
|
// surface the project is ever checked out on. Refusing loudly would make
|
|
742
742
|
// a correct local session look broken every time it started.
|
|
@@ -745,10 +745,34 @@ export function selectPhases(requested, materializeAt) {
|
|
|
745
745
|
return [requested];
|
|
746
746
|
}
|
|
747
747
|
return PHASES.filter(
|
|
748
|
-
phase => phase !== "secrets" || materializeAt
|
|
748
|
+
phase => phase !== "secrets" || materializesAtSetup(materializeAt)
|
|
749
749
|
);
|
|
750
750
|
}
|
|
751
751
|
|
|
752
|
+
/**
|
|
753
|
+
* Whether the setup run itself should materialize.
|
|
754
|
+
*
|
|
755
|
+
* `"both"` means the surface materializes in the setup run AND from the
|
|
756
|
+
* session-start hook, because on that surface either one alone has a hole: the
|
|
757
|
+
* setup run is skipped when a cached environment is reused, and the hook cannot
|
|
758
|
+
* fire when Claude Code's project directory is not the repository — which is
|
|
759
|
+
* every cloud environment configured with more than one repo.
|
|
760
|
+
* @param {string|null} materializeAt Surface capability.
|
|
761
|
+
* @returns {boolean} Whether to materialize during setup.
|
|
762
|
+
*/
|
|
763
|
+
export function materializesAtSetup(materializeAt) {
|
|
764
|
+
return materializeAt === "setup" || materializeAt === "both";
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
/**
|
|
768
|
+
* Whether the committed session-start hook should materialize.
|
|
769
|
+
* @param {string|null} materializeAt Surface capability.
|
|
770
|
+
* @returns {boolean} Whether the hook does the work.
|
|
771
|
+
*/
|
|
772
|
+
export function materializesAtSessionStart(materializeAt) {
|
|
773
|
+
return materializeAt === "session-start" || materializeAt === "both";
|
|
774
|
+
}
|
|
775
|
+
|
|
752
776
|
/**
|
|
753
777
|
* Read the surface the resolver detects, without duplicating its rules.
|
|
754
778
|
*
|
|
@@ -137,6 +137,7 @@ than stopping.
|
|
|
137
137
|
- **Install a credential manager you did not pick.**
|
|
138
138
|
- **Reinstall over a tool that is already there**, whatever installed it.
|
|
139
139
|
- **Install anything without `--install`.**
|
|
140
|
-
- **Install
|
|
141
|
-
with a pointer, because "not installed" and "cannot be installed by
|
|
142
|
-
different answers to the operator.
|
|
140
|
+
- **Install a tool whose vendor publishes no headless installer.** Such an entry is
|
|
141
|
+
reported as manual with a pointer, because "not installed" and "cannot be installed by
|
|
142
|
+
this tool" are different answers to the operator. No agent is currently in that state —
|
|
143
|
+
Antigravity was listed there in error and does publish a bootstrapper.
|
|
@@ -66,11 +66,13 @@ export const AGENTS = [
|
|
|
66
66
|
{
|
|
67
67
|
name: "agy",
|
|
68
68
|
label: "Antigravity",
|
|
69
|
-
kind: "
|
|
70
|
-
//
|
|
71
|
-
//
|
|
72
|
-
//
|
|
73
|
-
|
|
69
|
+
kind: "vendor-script",
|
|
70
|
+
// Google does publish a headless bootstrapper; this entry previously said
|
|
71
|
+
// otherwise and reported the agent as uninstallable. Confirmed live —
|
|
72
|
+
// `content-type: application/x-sh`, and the payload is a bash script that
|
|
73
|
+
// downloads and verifies the flat native build.
|
|
74
|
+
script: "https://antigravity.google/cli/install.sh",
|
|
75
|
+
selfUpdates: true,
|
|
74
76
|
},
|
|
75
77
|
{
|
|
76
78
|
name: "copilot",
|
|
@@ -56,7 +56,28 @@ export const SURFACES = {
|
|
|
56
56
|
"claude-web": {
|
|
57
57
|
materialized: true,
|
|
58
58
|
mayWriteValues: true,
|
|
59
|
-
|
|
59
|
+
// BOTH, and the two cover disjoint failures rather than duplicating work.
|
|
60
|
+
//
|
|
61
|
+
// The hook alone was the original design, for a real reason: this surface
|
|
62
|
+
// skips its setup script whenever a cached environment exists, so
|
|
63
|
+
// materializing only there would write values once and never refresh them.
|
|
64
|
+
//
|
|
65
|
+
// What that missed is that the hook is PROJECT-scoped — it lives in a
|
|
66
|
+
// repository's `.claude/settings.json` and only loads when Claude Code's
|
|
67
|
+
// project directory is that repository. A cloud environment configured with
|
|
68
|
+
// more than one repository starts in their parent:
|
|
69
|
+
//
|
|
70
|
+
// HOME=/root PWD=/home/user
|
|
71
|
+
// /home/user/backend /home/user/infrastructure
|
|
72
|
+
//
|
|
73
|
+
// `/home/user` is not a project root, so no settings load, no hook
|
|
74
|
+
// registers, and nothing materializes at all. Verified in a real session.
|
|
75
|
+
//
|
|
76
|
+
// So the setup run is the FLOOR — a fresh environment has its secrets even
|
|
77
|
+
// where the hook cannot fire — and the hook is the REFRESH, picking up
|
|
78
|
+
// rotation on resumed sessions that skip setup. A stale secret is
|
|
79
|
+
// recoverable; an absent one means the environment does not work.
|
|
80
|
+
materializeAt: "both",
|
|
60
81
|
},
|
|
61
82
|
};
|
|
62
83
|
|
|
@@ -736,7 +736,7 @@ export function selectPhases(requested, materializeAt) {
|
|
|
736
736
|
`unknown --phase "${requested}". Known: ${PHASES.join(", ")}.`
|
|
737
737
|
);
|
|
738
738
|
}
|
|
739
|
-
if (requested === "secrets" && materializeAt
|
|
739
|
+
if (requested === "secrets" && !materializesAtSessionStart(materializeAt)) {
|
|
740
740
|
// Not an error: the hook is committed to the repository and runs on every
|
|
741
741
|
// surface the project is ever checked out on. Refusing loudly would make
|
|
742
742
|
// a correct local session look broken every time it started.
|
|
@@ -745,10 +745,34 @@ export function selectPhases(requested, materializeAt) {
|
|
|
745
745
|
return [requested];
|
|
746
746
|
}
|
|
747
747
|
return PHASES.filter(
|
|
748
|
-
phase => phase !== "secrets" || materializeAt
|
|
748
|
+
phase => phase !== "secrets" || materializesAtSetup(materializeAt)
|
|
749
749
|
);
|
|
750
750
|
}
|
|
751
751
|
|
|
752
|
+
/**
|
|
753
|
+
* Whether the setup run itself should materialize.
|
|
754
|
+
*
|
|
755
|
+
* `"both"` means the surface materializes in the setup run AND from the
|
|
756
|
+
* session-start hook, because on that surface either one alone has a hole: the
|
|
757
|
+
* setup run is skipped when a cached environment is reused, and the hook cannot
|
|
758
|
+
* fire when Claude Code's project directory is not the repository — which is
|
|
759
|
+
* every cloud environment configured with more than one repo.
|
|
760
|
+
* @param {string|null} materializeAt Surface capability.
|
|
761
|
+
* @returns {boolean} Whether to materialize during setup.
|
|
762
|
+
*/
|
|
763
|
+
export function materializesAtSetup(materializeAt) {
|
|
764
|
+
return materializeAt === "setup" || materializeAt === "both";
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
/**
|
|
768
|
+
* Whether the committed session-start hook should materialize.
|
|
769
|
+
* @param {string|null} materializeAt Surface capability.
|
|
770
|
+
* @returns {boolean} Whether the hook does the work.
|
|
771
|
+
*/
|
|
772
|
+
export function materializesAtSessionStart(materializeAt) {
|
|
773
|
+
return materializeAt === "session-start" || materializeAt === "both";
|
|
774
|
+
}
|
|
775
|
+
|
|
752
776
|
/**
|
|
753
777
|
* Read the surface the resolver detects, without duplicating its rules.
|
|
754
778
|
*
|
|
@@ -137,6 +137,7 @@ than stopping.
|
|
|
137
137
|
- **Install a credential manager you did not pick.**
|
|
138
138
|
- **Reinstall over a tool that is already there**, whatever installed it.
|
|
139
139
|
- **Install anything without `--install`.**
|
|
140
|
-
- **Install
|
|
141
|
-
with a pointer, because "not installed" and "cannot be installed by
|
|
142
|
-
different answers to the operator.
|
|
140
|
+
- **Install a tool whose vendor publishes no headless installer.** Such an entry is
|
|
141
|
+
reported as manual with a pointer, because "not installed" and "cannot be installed by
|
|
142
|
+
this tool" are different answers to the operator. No agent is currently in that state —
|
|
143
|
+
Antigravity was listed there in error and does publish a bootstrapper.
|
|
@@ -66,11 +66,13 @@ export const AGENTS = [
|
|
|
66
66
|
{
|
|
67
67
|
name: "agy",
|
|
68
68
|
label: "Antigravity",
|
|
69
|
-
kind: "
|
|
70
|
-
//
|
|
71
|
-
//
|
|
72
|
-
//
|
|
73
|
-
|
|
69
|
+
kind: "vendor-script",
|
|
70
|
+
// Google does publish a headless bootstrapper; this entry previously said
|
|
71
|
+
// otherwise and reported the agent as uninstallable. Confirmed live —
|
|
72
|
+
// `content-type: application/x-sh`, and the payload is a bash script that
|
|
73
|
+
// downloads and verifies the flat native build.
|
|
74
|
+
script: "https://antigravity.google/cli/install.sh",
|
|
75
|
+
selfUpdates: true,
|
|
74
76
|
},
|
|
75
77
|
{
|
|
76
78
|
name: "copilot",
|
|
@@ -56,7 +56,28 @@ export const SURFACES = {
|
|
|
56
56
|
"claude-web": {
|
|
57
57
|
materialized: true,
|
|
58
58
|
mayWriteValues: true,
|
|
59
|
-
|
|
59
|
+
// BOTH, and the two cover disjoint failures rather than duplicating work.
|
|
60
|
+
//
|
|
61
|
+
// The hook alone was the original design, for a real reason: this surface
|
|
62
|
+
// skips its setup script whenever a cached environment exists, so
|
|
63
|
+
// materializing only there would write values once and never refresh them.
|
|
64
|
+
//
|
|
65
|
+
// What that missed is that the hook is PROJECT-scoped — it lives in a
|
|
66
|
+
// repository's `.claude/settings.json` and only loads when Claude Code's
|
|
67
|
+
// project directory is that repository. A cloud environment configured with
|
|
68
|
+
// more than one repository starts in their parent:
|
|
69
|
+
//
|
|
70
|
+
// HOME=/root PWD=/home/user
|
|
71
|
+
// /home/user/backend /home/user/infrastructure
|
|
72
|
+
//
|
|
73
|
+
// `/home/user` is not a project root, so no settings load, no hook
|
|
74
|
+
// registers, and nothing materializes at all. Verified in a real session.
|
|
75
|
+
//
|
|
76
|
+
// So the setup run is the FLOOR — a fresh environment has its secrets even
|
|
77
|
+
// where the hook cannot fire — and the hook is the REFRESH, picking up
|
|
78
|
+
// rotation on resumed sessions that skip setup. A stale secret is
|
|
79
|
+
// recoverable; an absent one means the environment does not work.
|
|
80
|
+
materializeAt: "both",
|
|
60
81
|
},
|
|
61
82
|
};
|
|
62
83
|
|
|
@@ -736,7 +736,7 @@ export function selectPhases(requested, materializeAt) {
|
|
|
736
736
|
`unknown --phase "${requested}". Known: ${PHASES.join(", ")}.`
|
|
737
737
|
);
|
|
738
738
|
}
|
|
739
|
-
if (requested === "secrets" && materializeAt
|
|
739
|
+
if (requested === "secrets" && !materializesAtSessionStart(materializeAt)) {
|
|
740
740
|
// Not an error: the hook is committed to the repository and runs on every
|
|
741
741
|
// surface the project is ever checked out on. Refusing loudly would make
|
|
742
742
|
// a correct local session look broken every time it started.
|
|
@@ -745,10 +745,34 @@ export function selectPhases(requested, materializeAt) {
|
|
|
745
745
|
return [requested];
|
|
746
746
|
}
|
|
747
747
|
return PHASES.filter(
|
|
748
|
-
phase => phase !== "secrets" || materializeAt
|
|
748
|
+
phase => phase !== "secrets" || materializesAtSetup(materializeAt)
|
|
749
749
|
);
|
|
750
750
|
}
|
|
751
751
|
|
|
752
|
+
/**
|
|
753
|
+
* Whether the setup run itself should materialize.
|
|
754
|
+
*
|
|
755
|
+
* `"both"` means the surface materializes in the setup run AND from the
|
|
756
|
+
* session-start hook, because on that surface either one alone has a hole: the
|
|
757
|
+
* setup run is skipped when a cached environment is reused, and the hook cannot
|
|
758
|
+
* fire when Claude Code's project directory is not the repository — which is
|
|
759
|
+
* every cloud environment configured with more than one repo.
|
|
760
|
+
* @param {string|null} materializeAt Surface capability.
|
|
761
|
+
* @returns {boolean} Whether to materialize during setup.
|
|
762
|
+
*/
|
|
763
|
+
export function materializesAtSetup(materializeAt) {
|
|
764
|
+
return materializeAt === "setup" || materializeAt === "both";
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
/**
|
|
768
|
+
* Whether the committed session-start hook should materialize.
|
|
769
|
+
* @param {string|null} materializeAt Surface capability.
|
|
770
|
+
* @returns {boolean} Whether the hook does the work.
|
|
771
|
+
*/
|
|
772
|
+
export function materializesAtSessionStart(materializeAt) {
|
|
773
|
+
return materializeAt === "session-start" || materializeAt === "both";
|
|
774
|
+
}
|
|
775
|
+
|
|
752
776
|
/**
|
|
753
777
|
* Read the surface the resolver detects, without duplicating its rules.
|
|
754
778
|
*
|
|
@@ -137,6 +137,7 @@ than stopping.
|
|
|
137
137
|
- **Install a credential manager you did not pick.**
|
|
138
138
|
- **Reinstall over a tool that is already there**, whatever installed it.
|
|
139
139
|
- **Install anything without `--install`.**
|
|
140
|
-
- **Install
|
|
141
|
-
with a pointer, because "not installed" and "cannot be installed by
|
|
142
|
-
different answers to the operator.
|
|
140
|
+
- **Install a tool whose vendor publishes no headless installer.** Such an entry is
|
|
141
|
+
reported as manual with a pointer, because "not installed" and "cannot be installed by
|
|
142
|
+
this tool" are different answers to the operator. No agent is currently in that state —
|
|
143
|
+
Antigravity was listed there in error and does publish a bootstrapper.
|
|
@@ -66,11 +66,13 @@ export const AGENTS = [
|
|
|
66
66
|
{
|
|
67
67
|
name: "agy",
|
|
68
68
|
label: "Antigravity",
|
|
69
|
-
kind: "
|
|
70
|
-
//
|
|
71
|
-
//
|
|
72
|
-
//
|
|
73
|
-
|
|
69
|
+
kind: "vendor-script",
|
|
70
|
+
// Google does publish a headless bootstrapper; this entry previously said
|
|
71
|
+
// otherwise and reported the agent as uninstallable. Confirmed live —
|
|
72
|
+
// `content-type: application/x-sh`, and the payload is a bash script that
|
|
73
|
+
// downloads and verifies the flat native build.
|
|
74
|
+
script: "https://antigravity.google/cli/install.sh",
|
|
75
|
+
selfUpdates: true,
|
|
74
76
|
},
|
|
75
77
|
{
|
|
76
78
|
name: "copilot",
|
|
@@ -56,7 +56,28 @@ export const SURFACES = {
|
|
|
56
56
|
"claude-web": {
|
|
57
57
|
materialized: true,
|
|
58
58
|
mayWriteValues: true,
|
|
59
|
-
|
|
59
|
+
// BOTH, and the two cover disjoint failures rather than duplicating work.
|
|
60
|
+
//
|
|
61
|
+
// The hook alone was the original design, for a real reason: this surface
|
|
62
|
+
// skips its setup script whenever a cached environment exists, so
|
|
63
|
+
// materializing only there would write values once and never refresh them.
|
|
64
|
+
//
|
|
65
|
+
// What that missed is that the hook is PROJECT-scoped — it lives in a
|
|
66
|
+
// repository's `.claude/settings.json` and only loads when Claude Code's
|
|
67
|
+
// project directory is that repository. A cloud environment configured with
|
|
68
|
+
// more than one repository starts in their parent:
|
|
69
|
+
//
|
|
70
|
+
// HOME=/root PWD=/home/user
|
|
71
|
+
// /home/user/backend /home/user/infrastructure
|
|
72
|
+
//
|
|
73
|
+
// `/home/user` is not a project root, so no settings load, no hook
|
|
74
|
+
// registers, and nothing materializes at all. Verified in a real session.
|
|
75
|
+
//
|
|
76
|
+
// So the setup run is the FLOOR — a fresh environment has its secrets even
|
|
77
|
+
// where the hook cannot fire — and the hook is the REFRESH, picking up
|
|
78
|
+
// rotation on resumed sessions that skip setup. A stale secret is
|
|
79
|
+
// recoverable; an absent one means the environment does not work.
|
|
80
|
+
materializeAt: "both",
|
|
60
81
|
},
|
|
61
82
|
};
|
|
62
83
|
|
|
@@ -736,7 +736,7 @@ export function selectPhases(requested, materializeAt) {
|
|
|
736
736
|
`unknown --phase "${requested}". Known: ${PHASES.join(", ")}.`
|
|
737
737
|
);
|
|
738
738
|
}
|
|
739
|
-
if (requested === "secrets" && materializeAt
|
|
739
|
+
if (requested === "secrets" && !materializesAtSessionStart(materializeAt)) {
|
|
740
740
|
// Not an error: the hook is committed to the repository and runs on every
|
|
741
741
|
// surface the project is ever checked out on. Refusing loudly would make
|
|
742
742
|
// a correct local session look broken every time it started.
|
|
@@ -745,10 +745,34 @@ export function selectPhases(requested, materializeAt) {
|
|
|
745
745
|
return [requested];
|
|
746
746
|
}
|
|
747
747
|
return PHASES.filter(
|
|
748
|
-
phase => phase !== "secrets" || materializeAt
|
|
748
|
+
phase => phase !== "secrets" || materializesAtSetup(materializeAt)
|
|
749
749
|
);
|
|
750
750
|
}
|
|
751
751
|
|
|
752
|
+
/**
|
|
753
|
+
* Whether the setup run itself should materialize.
|
|
754
|
+
*
|
|
755
|
+
* `"both"` means the surface materializes in the setup run AND from the
|
|
756
|
+
* session-start hook, because on that surface either one alone has a hole: the
|
|
757
|
+
* setup run is skipped when a cached environment is reused, and the hook cannot
|
|
758
|
+
* fire when Claude Code's project directory is not the repository — which is
|
|
759
|
+
* every cloud environment configured with more than one repo.
|
|
760
|
+
* @param {string|null} materializeAt Surface capability.
|
|
761
|
+
* @returns {boolean} Whether to materialize during setup.
|
|
762
|
+
*/
|
|
763
|
+
export function materializesAtSetup(materializeAt) {
|
|
764
|
+
return materializeAt === "setup" || materializeAt === "both";
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
/**
|
|
768
|
+
* Whether the committed session-start hook should materialize.
|
|
769
|
+
* @param {string|null} materializeAt Surface capability.
|
|
770
|
+
* @returns {boolean} Whether the hook does the work.
|
|
771
|
+
*/
|
|
772
|
+
export function materializesAtSessionStart(materializeAt) {
|
|
773
|
+
return materializeAt === "session-start" || materializeAt === "both";
|
|
774
|
+
}
|
|
775
|
+
|
|
752
776
|
/**
|
|
753
777
|
* Read the surface the resolver detects, without duplicating its rules.
|
|
754
778
|
*
|
|
@@ -137,6 +137,7 @@ than stopping.
|
|
|
137
137
|
- **Install a credential manager you did not pick.**
|
|
138
138
|
- **Reinstall over a tool that is already there**, whatever installed it.
|
|
139
139
|
- **Install anything without `--install`.**
|
|
140
|
-
- **Install
|
|
141
|
-
with a pointer, because "not installed" and "cannot be installed by
|
|
142
|
-
different answers to the operator.
|
|
140
|
+
- **Install a tool whose vendor publishes no headless installer.** Such an entry is
|
|
141
|
+
reported as manual with a pointer, because "not installed" and "cannot be installed by
|
|
142
|
+
this tool" are different answers to the operator. No agent is currently in that state —
|
|
143
|
+
Antigravity was listed there in error and does publish a bootstrapper.
|