gsd-pi 2.30.0-dev.54ac83b → 2.30.0-dev.7e1bbce
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/resources/extensions/gsd/auto-worktree.ts +8 -12
- package/dist/resources/extensions/gsd/guided-flow.ts +0 -3
- package/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +0 -14
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +0 -4
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.js +0 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +0 -7
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
- package/packages/pi-coding-agent/src/core/agent-session.ts +0 -14
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +0 -5
- package/packages/pi-coding-agent/src/core/extensions/runner.ts +0 -1
- package/packages/pi-coding-agent/src/core/extensions/types.ts +0 -8
- package/src/resources/extensions/gsd/auto-worktree.ts +8 -12
- package/src/resources/extensions/gsd/guided-flow.ts +0 -3
- package/dist/resources/extensions/aws-auth/index.ts +0 -144
- package/src/resources/extensions/aws-auth/index.ts +0 -144
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AWS Auth Refresh Extension
|
|
3
|
-
*
|
|
4
|
-
* Automatically refreshes AWS credentials when Bedrock API requests fail
|
|
5
|
-
* with authentication/token errors, then retries the user's message.
|
|
6
|
-
*
|
|
7
|
-
* ## How it works
|
|
8
|
-
*
|
|
9
|
-
* Hooks into `agent_end` to check if the last assistant message failed with
|
|
10
|
-
* an AWS auth error (expired SSO token, missing credentials, etc.). If so:
|
|
11
|
-
*
|
|
12
|
-
* 1. Runs the configured `awsAuthRefresh` command (e.g. `aws sso login`)
|
|
13
|
-
* 2. Streams the SSO auth URL and verification code to the TUI so users
|
|
14
|
-
* can copy/paste if the browser doesn't auto-open
|
|
15
|
-
* 3. Calls `retryLastTurn()` which removes the failed assistant response
|
|
16
|
-
* and re-runs the agent from the user's original message
|
|
17
|
-
*
|
|
18
|
-
* ## Activation
|
|
19
|
-
*
|
|
20
|
-
* This extension is completely inert unless BOTH conditions are met:
|
|
21
|
-
* 1. A Bedrock API request fails with a recognized AWS auth error
|
|
22
|
-
* 2. `awsAuthRefresh` is configured in settings.json
|
|
23
|
-
*
|
|
24
|
-
* Non-Bedrock users and Bedrock users without `awsAuthRefresh` configured
|
|
25
|
-
* are not affected in any way.
|
|
26
|
-
*
|
|
27
|
-
* ## Setup
|
|
28
|
-
*
|
|
29
|
-
* Add to ~/.gsd/agent/settings.json (or project-level .gsd/settings.json):
|
|
30
|
-
*
|
|
31
|
-
* { "awsAuthRefresh": "aws sso login --profile my-profile" }
|
|
32
|
-
*
|
|
33
|
-
* ## Matched error patterns
|
|
34
|
-
*
|
|
35
|
-
* The extension recognizes errors from the AWS SDK, Bedrock, and SSO
|
|
36
|
-
* credential providers including:
|
|
37
|
-
* - ExpiredTokenException / ExpiredToken
|
|
38
|
-
* - The security token included in the request is expired
|
|
39
|
-
* - The SSO session associated with this profile has expired or is invalid
|
|
40
|
-
* - Unable to locate credentials / Could not load credentials
|
|
41
|
-
* - UnrecognizedClientException
|
|
42
|
-
* - Error loading SSO Token / Token does not exist
|
|
43
|
-
* - SSOTokenProviderFailure
|
|
44
|
-
*/
|
|
45
|
-
|
|
46
|
-
import { exec } from "node:child_process";
|
|
47
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
48
|
-
import { join } from "node:path";
|
|
49
|
-
import { homedir } from "node:os";
|
|
50
|
-
import type { ExtensionAPI } from "@gsd/pi-coding-agent";
|
|
51
|
-
|
|
52
|
-
/** Matches AWS SDK / Bedrock / SSO credential and token errors. */
|
|
53
|
-
const AWS_AUTH_ERROR_RE =
|
|
54
|
-
/ExpiredToken|security token.*expired|unable to locate credentials|SSO.*(?:session|token).*(?:expired|not found|invalid)|UnrecognizedClient|Could not load credentials|Invalid identity token|token is expired|credentials.*(?:could not|cannot|failed to).*(?:load|resolve|find)|The.*token.*is.*not.*valid|token has expired|SSOTokenProviderFailure|Error loading SSO Token|Token.*does not exist/i;
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Reads the `awsAuthRefresh` command from settings.json.
|
|
58
|
-
* Checks project-level first, then global (~/.gsd/agent/settings.json).
|
|
59
|
-
*/
|
|
60
|
-
function getAwsAuthRefreshCommand(): string | undefined {
|
|
61
|
-
const configDir = process.env.PI_CONFIG_DIR || ".gsd";
|
|
62
|
-
const paths = [
|
|
63
|
-
join(process.cwd(), configDir, "settings.json"),
|
|
64
|
-
join(homedir(), configDir, "agent", "settings.json"),
|
|
65
|
-
];
|
|
66
|
-
for (const settingsPath of paths) {
|
|
67
|
-
if (!existsSync(settingsPath)) continue;
|
|
68
|
-
try {
|
|
69
|
-
const settings = JSON.parse(readFileSync(settingsPath, "utf-8"));
|
|
70
|
-
if (settings.awsAuthRefresh) return settings.awsAuthRefresh;
|
|
71
|
-
} catch {}
|
|
72
|
-
}
|
|
73
|
-
return undefined;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Runs the refresh command with a 2-minute timeout (for SSO browser flows).
|
|
78
|
-
* Streams stdout/stderr to capture and display the SSO auth URL and
|
|
79
|
-
* verification code in real-time via TUI notifications.
|
|
80
|
-
*/
|
|
81
|
-
async function runRefresh(
|
|
82
|
-
command: string,
|
|
83
|
-
notify: (msg: string, level: "info" | "warning" | "error") => void,
|
|
84
|
-
): Promise<boolean> {
|
|
85
|
-
notify("Refreshing AWS credentials...", "info");
|
|
86
|
-
try {
|
|
87
|
-
await new Promise<void>((resolve, reject) => {
|
|
88
|
-
const child = exec(command, { timeout: 120_000, env: { ...process.env } });
|
|
89
|
-
const onData = (data: Buffer | string) => {
|
|
90
|
-
const text = data.toString();
|
|
91
|
-
const urlMatch = text.match(/https?:\/\/\S+/);
|
|
92
|
-
if (urlMatch) {
|
|
93
|
-
notify(`Open this URL if the browser didn't launch: ${urlMatch[0]}`, "warning");
|
|
94
|
-
}
|
|
95
|
-
const codeMatch = text.match(/code[:\s]+([A-Z]{4}-[A-Z]{4})/i);
|
|
96
|
-
if (codeMatch) {
|
|
97
|
-
notify(`Verification code: ${codeMatch[1]}`, "info");
|
|
98
|
-
}
|
|
99
|
-
};
|
|
100
|
-
child.stdout?.on("data", onData);
|
|
101
|
-
child.stderr?.on("data", onData);
|
|
102
|
-
child.on("close", (code) => {
|
|
103
|
-
if (code === 0) resolve();
|
|
104
|
-
else reject(new Error(`Refresh command exited with code ${code}`));
|
|
105
|
-
});
|
|
106
|
-
child.on("error", reject);
|
|
107
|
-
});
|
|
108
|
-
notify("AWS credentials refreshed successfully ✓", "info");
|
|
109
|
-
return true;
|
|
110
|
-
} catch (error) {
|
|
111
|
-
const msg = error instanceof Error ? error.message : String(error);
|
|
112
|
-
const isTimeout = /timed out|ETIMEDOUT|killed/i.test(msg);
|
|
113
|
-
if (isTimeout) {
|
|
114
|
-
notify("AWS credential refresh timed out. The SSO login may have been cancelled or the browser window was closed.", "error");
|
|
115
|
-
} else {
|
|
116
|
-
notify(`AWS credential refresh failed: ${msg}`, "error");
|
|
117
|
-
}
|
|
118
|
-
return false;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
export default function (pi: ExtensionAPI) {
|
|
123
|
-
pi.on("agent_end", async (event, ctx) => {
|
|
124
|
-
const refreshCommand = getAwsAuthRefreshCommand();
|
|
125
|
-
if (!refreshCommand) return;
|
|
126
|
-
|
|
127
|
-
const messages = event.messages;
|
|
128
|
-
const lastAssistant = messages[messages.length - 1];
|
|
129
|
-
if (
|
|
130
|
-
!lastAssistant ||
|
|
131
|
-
lastAssistant.role !== "assistant" ||
|
|
132
|
-
!("errorMessage" in lastAssistant) ||
|
|
133
|
-
!lastAssistant.errorMessage ||
|
|
134
|
-
!AWS_AUTH_ERROR_RE.test(lastAssistant.errorMessage)
|
|
135
|
-
) {
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
const refreshed = await runRefresh(refreshCommand, (m, level) => ctx.ui.notify(m, level));
|
|
140
|
-
if (!refreshed) return;
|
|
141
|
-
|
|
142
|
-
pi.retryLastTurn();
|
|
143
|
-
});
|
|
144
|
-
}
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AWS Auth Refresh Extension
|
|
3
|
-
*
|
|
4
|
-
* Automatically refreshes AWS credentials when Bedrock API requests fail
|
|
5
|
-
* with authentication/token errors, then retries the user's message.
|
|
6
|
-
*
|
|
7
|
-
* ## How it works
|
|
8
|
-
*
|
|
9
|
-
* Hooks into `agent_end` to check if the last assistant message failed with
|
|
10
|
-
* an AWS auth error (expired SSO token, missing credentials, etc.). If so:
|
|
11
|
-
*
|
|
12
|
-
* 1. Runs the configured `awsAuthRefresh` command (e.g. `aws sso login`)
|
|
13
|
-
* 2. Streams the SSO auth URL and verification code to the TUI so users
|
|
14
|
-
* can copy/paste if the browser doesn't auto-open
|
|
15
|
-
* 3. Calls `retryLastTurn()` which removes the failed assistant response
|
|
16
|
-
* and re-runs the agent from the user's original message
|
|
17
|
-
*
|
|
18
|
-
* ## Activation
|
|
19
|
-
*
|
|
20
|
-
* This extension is completely inert unless BOTH conditions are met:
|
|
21
|
-
* 1. A Bedrock API request fails with a recognized AWS auth error
|
|
22
|
-
* 2. `awsAuthRefresh` is configured in settings.json
|
|
23
|
-
*
|
|
24
|
-
* Non-Bedrock users and Bedrock users without `awsAuthRefresh` configured
|
|
25
|
-
* are not affected in any way.
|
|
26
|
-
*
|
|
27
|
-
* ## Setup
|
|
28
|
-
*
|
|
29
|
-
* Add to ~/.gsd/agent/settings.json (or project-level .gsd/settings.json):
|
|
30
|
-
*
|
|
31
|
-
* { "awsAuthRefresh": "aws sso login --profile my-profile" }
|
|
32
|
-
*
|
|
33
|
-
* ## Matched error patterns
|
|
34
|
-
*
|
|
35
|
-
* The extension recognizes errors from the AWS SDK, Bedrock, and SSO
|
|
36
|
-
* credential providers including:
|
|
37
|
-
* - ExpiredTokenException / ExpiredToken
|
|
38
|
-
* - The security token included in the request is expired
|
|
39
|
-
* - The SSO session associated with this profile has expired or is invalid
|
|
40
|
-
* - Unable to locate credentials / Could not load credentials
|
|
41
|
-
* - UnrecognizedClientException
|
|
42
|
-
* - Error loading SSO Token / Token does not exist
|
|
43
|
-
* - SSOTokenProviderFailure
|
|
44
|
-
*/
|
|
45
|
-
|
|
46
|
-
import { exec } from "node:child_process";
|
|
47
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
48
|
-
import { join } from "node:path";
|
|
49
|
-
import { homedir } from "node:os";
|
|
50
|
-
import type { ExtensionAPI } from "@gsd/pi-coding-agent";
|
|
51
|
-
|
|
52
|
-
/** Matches AWS SDK / Bedrock / SSO credential and token errors. */
|
|
53
|
-
const AWS_AUTH_ERROR_RE =
|
|
54
|
-
/ExpiredToken|security token.*expired|unable to locate credentials|SSO.*(?:session|token).*(?:expired|not found|invalid)|UnrecognizedClient|Could not load credentials|Invalid identity token|token is expired|credentials.*(?:could not|cannot|failed to).*(?:load|resolve|find)|The.*token.*is.*not.*valid|token has expired|SSOTokenProviderFailure|Error loading SSO Token|Token.*does not exist/i;
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Reads the `awsAuthRefresh` command from settings.json.
|
|
58
|
-
* Checks project-level first, then global (~/.gsd/agent/settings.json).
|
|
59
|
-
*/
|
|
60
|
-
function getAwsAuthRefreshCommand(): string | undefined {
|
|
61
|
-
const configDir = process.env.PI_CONFIG_DIR || ".gsd";
|
|
62
|
-
const paths = [
|
|
63
|
-
join(process.cwd(), configDir, "settings.json"),
|
|
64
|
-
join(homedir(), configDir, "agent", "settings.json"),
|
|
65
|
-
];
|
|
66
|
-
for (const settingsPath of paths) {
|
|
67
|
-
if (!existsSync(settingsPath)) continue;
|
|
68
|
-
try {
|
|
69
|
-
const settings = JSON.parse(readFileSync(settingsPath, "utf-8"));
|
|
70
|
-
if (settings.awsAuthRefresh) return settings.awsAuthRefresh;
|
|
71
|
-
} catch {}
|
|
72
|
-
}
|
|
73
|
-
return undefined;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Runs the refresh command with a 2-minute timeout (for SSO browser flows).
|
|
78
|
-
* Streams stdout/stderr to capture and display the SSO auth URL and
|
|
79
|
-
* verification code in real-time via TUI notifications.
|
|
80
|
-
*/
|
|
81
|
-
async function runRefresh(
|
|
82
|
-
command: string,
|
|
83
|
-
notify: (msg: string, level: "info" | "warning" | "error") => void,
|
|
84
|
-
): Promise<boolean> {
|
|
85
|
-
notify("Refreshing AWS credentials...", "info");
|
|
86
|
-
try {
|
|
87
|
-
await new Promise<void>((resolve, reject) => {
|
|
88
|
-
const child = exec(command, { timeout: 120_000, env: { ...process.env } });
|
|
89
|
-
const onData = (data: Buffer | string) => {
|
|
90
|
-
const text = data.toString();
|
|
91
|
-
const urlMatch = text.match(/https?:\/\/\S+/);
|
|
92
|
-
if (urlMatch) {
|
|
93
|
-
notify(`Open this URL if the browser didn't launch: ${urlMatch[0]}`, "warning");
|
|
94
|
-
}
|
|
95
|
-
const codeMatch = text.match(/code[:\s]+([A-Z]{4}-[A-Z]{4})/i);
|
|
96
|
-
if (codeMatch) {
|
|
97
|
-
notify(`Verification code: ${codeMatch[1]}`, "info");
|
|
98
|
-
}
|
|
99
|
-
};
|
|
100
|
-
child.stdout?.on("data", onData);
|
|
101
|
-
child.stderr?.on("data", onData);
|
|
102
|
-
child.on("close", (code) => {
|
|
103
|
-
if (code === 0) resolve();
|
|
104
|
-
else reject(new Error(`Refresh command exited with code ${code}`));
|
|
105
|
-
});
|
|
106
|
-
child.on("error", reject);
|
|
107
|
-
});
|
|
108
|
-
notify("AWS credentials refreshed successfully ✓", "info");
|
|
109
|
-
return true;
|
|
110
|
-
} catch (error) {
|
|
111
|
-
const msg = error instanceof Error ? error.message : String(error);
|
|
112
|
-
const isTimeout = /timed out|ETIMEDOUT|killed/i.test(msg);
|
|
113
|
-
if (isTimeout) {
|
|
114
|
-
notify("AWS credential refresh timed out. The SSO login may have been cancelled or the browser window was closed.", "error");
|
|
115
|
-
} else {
|
|
116
|
-
notify(`AWS credential refresh failed: ${msg}`, "error");
|
|
117
|
-
}
|
|
118
|
-
return false;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
export default function (pi: ExtensionAPI) {
|
|
123
|
-
pi.on("agent_end", async (event, ctx) => {
|
|
124
|
-
const refreshCommand = getAwsAuthRefreshCommand();
|
|
125
|
-
if (!refreshCommand) return;
|
|
126
|
-
|
|
127
|
-
const messages = event.messages;
|
|
128
|
-
const lastAssistant = messages[messages.length - 1];
|
|
129
|
-
if (
|
|
130
|
-
!lastAssistant ||
|
|
131
|
-
lastAssistant.role !== "assistant" ||
|
|
132
|
-
!("errorMessage" in lastAssistant) ||
|
|
133
|
-
!lastAssistant.errorMessage ||
|
|
134
|
-
!AWS_AUTH_ERROR_RE.test(lastAssistant.errorMessage)
|
|
135
|
-
) {
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
const refreshed = await runRefresh(refreshCommand, (m, level) => ctx.ui.notify(m, level));
|
|
140
|
-
if (!refreshed) return;
|
|
141
|
-
|
|
142
|
-
pi.retryLastTurn();
|
|
143
|
-
});
|
|
144
|
-
}
|