agyx 0.1.2 → 0.1.3
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/README.md +39 -14
- package/dist/src/cli.js +150 -99
- package/dist/src/cli.js.map +1 -1
- package/dist/src/color.d.ts +9 -0
- package/dist/src/color.js +28 -0
- package/dist/src/color.js.map +1 -0
- package/dist/src/config.d.ts +28 -4
- package/dist/src/config.js +89 -21
- package/dist/src/config.js.map +1 -1
- package/dist/src/coordinator.d.ts +12 -2
- package/dist/src/coordinator.js +265 -11
- package/dist/src/coordinator.js.map +1 -1
- package/dist/src/eligibility.d.ts +4 -0
- package/dist/src/eligibility.js +10 -0
- package/dist/src/eligibility.js.map +1 -0
- package/dist/src/google_auth.d.ts +1 -0
- package/dist/src/google_auth.js +42 -0
- package/dist/src/google_auth.js.map +1 -0
- package/dist/src/install.d.ts +2 -0
- package/dist/src/install.js +24 -7
- package/dist/src/install.js.map +1 -1
- package/dist/src/keychain.js +2 -2
- package/dist/src/keychain.js.map +1 -1
- package/dist/src/onboarding.d.ts +1 -0
- package/dist/src/onboarding.js +87 -0
- package/dist/src/onboarding.js.map +1 -0
- package/dist/src/profile_view.d.ts +22 -0
- package/dist/src/profile_view.js +77 -0
- package/dist/src/profile_view.js.map +1 -0
- package/dist/src/quota.d.ts +1 -0
- package/dist/src/quota.js +3 -0
- package/dist/src/quota.js.map +1 -1
- package/dist/src/selection.d.ts +1 -1
- package/dist/src/selection.js +18 -1
- package/dist/src/selection.js.map +1 -1
- package/dist/src/session.js +54 -31
- package/dist/src/session.js.map +1 -1
- package/dist/src/ui.d.ts +19 -0
- package/dist/src/ui.js +306 -0
- package/dist/src/ui.js.map +1 -0
- package/package.json +8 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function detectCredentialEmail(credential: Buffer): Promise<string | undefined>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
function parseCredential(credential) {
|
|
2
|
+
const value = credential.toString("utf8").trim();
|
|
3
|
+
const prefix = "go-keyring-base64:";
|
|
4
|
+
try {
|
|
5
|
+
const json = value.startsWith(prefix)
|
|
6
|
+
? Buffer.from(value.slice(prefix.length), "base64").toString("utf8")
|
|
7
|
+
: value;
|
|
8
|
+
return JSON.parse(json);
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
async function fetchEmailFromUserInfo(accessToken) {
|
|
15
|
+
const response = await fetch("https://www.googleapis.com/oauth2/v2/userinfo", {
|
|
16
|
+
headers: { Authorization: `Bearer ${accessToken}` },
|
|
17
|
+
});
|
|
18
|
+
if (!response.ok)
|
|
19
|
+
return undefined;
|
|
20
|
+
const body = await response.json();
|
|
21
|
+
return typeof body.email === "string" ? body.email : undefined;
|
|
22
|
+
}
|
|
23
|
+
async function fetchEmailFromTokenInfo(accessToken) {
|
|
24
|
+
const response = await fetch(`https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=${encodeURIComponent(accessToken)}`);
|
|
25
|
+
if (!response.ok)
|
|
26
|
+
return undefined;
|
|
27
|
+
const body = await response.json();
|
|
28
|
+
return typeof body.email === "string" ? body.email : undefined;
|
|
29
|
+
}
|
|
30
|
+
export async function detectCredentialEmail(credential) {
|
|
31
|
+
const accessToken = parseCredential(credential)?.token?.access_token;
|
|
32
|
+
if (!accessToken)
|
|
33
|
+
return undefined;
|
|
34
|
+
try {
|
|
35
|
+
return await fetchEmailFromUserInfo(accessToken)
|
|
36
|
+
?? await fetchEmailFromTokenInfo(accessToken);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=google_auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"google_auth.js","sourceRoot":"","sources":["../../src/google_auth.ts"],"names":[],"mappings":"AAMA,SAAS,eAAe,CAAC,UAAkB;IACzC,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IACjD,MAAM,MAAM,GAAG,oBAAoB,CAAC;IACpC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC;YACnC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;YACpE,CAAC,CAAC,KAAK,CAAC;QACV,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAA4B,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,sBAAsB,CAAC,WAAmB;IACvD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,+CAA+C,EAAE;QAC5E,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,WAAW,EAAE,EAAE;KACpD,CAAC,CAAC;IACH,IAAI,CAAC,QAAQ,CAAC,EAAE;QAAE,OAAO,SAAS,CAAC;IACnC,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAyB,CAAC;IAC1D,OAAO,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACjE,CAAC;AAED,KAAK,UAAU,uBAAuB,CAAC,WAAmB;IACxD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAC1B,+DAA+D,kBAAkB,CAAC,WAAW,CAAC,EAAE,CACjG,CAAC;IACF,IAAI,CAAC,QAAQ,CAAC,EAAE;QAAE,OAAO,SAAS,CAAC;IACnC,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAyB,CAAC;IAC1D,OAAO,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACjE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,UAAkB;IAElB,MAAM,WAAW,GAAG,eAAe,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,YAAY,CAAC;IACrE,IAAI,CAAC,WAAW;QAAE,OAAO,SAAS,CAAC;IACnC,IAAI,CAAC;QACH,OAAO,MAAM,sBAAsB,CAAC,WAAW,CAAC;eAC3C,MAAM,uBAAuB,CAAC,WAAW,CAAC,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
|
package/dist/src/install.d.ts
CHANGED
package/dist/src/install.js
CHANGED
|
@@ -5,28 +5,45 @@ import { ensureParent } from "./config.js";
|
|
|
5
5
|
import { findRealAgy } from "./processes.js";
|
|
6
6
|
const startMarker = "# >>> agyx >>>";
|
|
7
7
|
const endMarker = "# <<< agyx <<<";
|
|
8
|
+
export function shellIntegrationPath() {
|
|
9
|
+
const shell = process.env.SHELL?.split("/").at(-1) ?? "zsh";
|
|
10
|
+
return shell === "bash"
|
|
11
|
+
? join(homedir(), ".bashrc")
|
|
12
|
+
: join(homedir(), ".zshrc");
|
|
13
|
+
}
|
|
8
14
|
export function shellInit() {
|
|
9
15
|
return `agy() { command agyx session -- "$@"; }`;
|
|
10
16
|
}
|
|
17
|
+
export async function shellIntegrationInstalled() {
|
|
18
|
+
const rcPath = shellIntegrationPath();
|
|
19
|
+
try {
|
|
20
|
+
return (await readFile(rcPath, "utf8")).includes(startMarker);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
11
26
|
export async function installShellIntegration() {
|
|
12
27
|
await findRealAgy();
|
|
13
|
-
const
|
|
14
|
-
const rcPath = shell === "bash"
|
|
15
|
-
? join(homedir(), ".bashrc")
|
|
16
|
-
: join(homedir(), ".zshrc");
|
|
28
|
+
const rcPath = shellIntegrationPath();
|
|
17
29
|
await ensureParent(rcPath);
|
|
18
30
|
let content = "";
|
|
31
|
+
let existing = true;
|
|
19
32
|
try {
|
|
20
33
|
content = await readFile(rcPath, "utf8");
|
|
21
34
|
}
|
|
22
|
-
catch {
|
|
35
|
+
catch {
|
|
36
|
+
existing = false;
|
|
37
|
+
}
|
|
23
38
|
const block = `${startMarker}\n${shellInit()}\n${endMarker}`;
|
|
24
39
|
const pattern = new RegExp(`${startMarker}[\\s\\S]*?${endMarker}`, "m");
|
|
40
|
+
const trimmed = content.trimEnd();
|
|
25
41
|
content = pattern.test(content)
|
|
26
42
|
? content.replace(pattern, block)
|
|
27
|
-
: `${
|
|
43
|
+
: `${trimmed ? `${trimmed}\n\n` : ""}${block}\n`;
|
|
28
44
|
await writeFile(rcPath, content, { mode: 0o600 });
|
|
29
|
-
|
|
45
|
+
if (!existing)
|
|
46
|
+
await chmod(rcPath, 0o600);
|
|
30
47
|
return rcPath;
|
|
31
48
|
}
|
|
32
49
|
//# sourceMappingURL=install.js.map
|
package/dist/src/install.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/install.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,MAAM,WAAW,GAAG,gBAAgB,CAAC;AACrC,MAAM,SAAS,GAAG,gBAAgB,CAAC;AAEnC,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/install.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,MAAM,WAAW,GAAG,gBAAgB,CAAC;AACrC,MAAM,SAAS,GAAG,gBAAgB,CAAC;AAEnC,MAAM,UAAU,oBAAoB;IAClC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC;IAC5D,OAAO,KAAK,KAAK,MAAM;QACrB,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC;QAC5B,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,SAAS;IACvB,OAAO,yCAAyC,CAAC;AACnD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,yBAAyB;IAC7C,MAAM,MAAM,GAAG,oBAAoB,EAAE,CAAC;IACtC,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAChE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB;IAC3C,MAAM,WAAW,EAAE,CAAC;IACpB,MAAM,MAAM,GAAG,oBAAoB,EAAE,CAAC;IACtC,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;IAC3B,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,IAAI,QAAQ,GAAG,IAAI,CAAC;IACpB,IAAI,CAAC;QAAC,OAAO,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,CAAC;IACjD,MAAM,CAAC;QAAC,QAAQ,GAAG,KAAK,CAAC;IAAC,CAAC;IAC3B,MAAM,KAAK,GAAG,GAAG,WAAW,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,CAAC;IAC7D,MAAM,OAAO,GAAG,IAAI,MAAM,CAAC,GAAG,WAAW,aAAa,SAAS,EAAE,EAAE,GAAG,CAAC,CAAC;IACxE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAClC,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;QAC7B,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC;QACjC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IACnD,MAAM,SAAS,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAClD,IAAI,CAAC,QAAQ;QAAE,MAAM,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC1C,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/src/keychain.js
CHANGED
|
@@ -27,8 +27,8 @@ async function write(service, account, credential, trustedApplications) {
|
|
|
27
27
|
for (const application of trustedApplications) {
|
|
28
28
|
args.push("-T", application);
|
|
29
29
|
}
|
|
30
|
-
args.push("-
|
|
31
|
-
await run(security, args
|
|
30
|
+
args.push("-X", credential.toString("hex"));
|
|
31
|
+
await run(security, args);
|
|
32
32
|
}
|
|
33
33
|
export const keychain = {
|
|
34
34
|
readActive: () => read(activeService, activeAccount),
|
package/dist/src/keychain.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keychain.js","sourceRoot":"","sources":["../../src/keychain.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,QAAQ,GAAG,mBAAmB,CAAC;AACrC,MAAM,aAAa,GAAG,QAAQ,CAAC;AAC/B,MAAM,aAAa,GAAG,aAAa,CAAC;AACpC,MAAM,YAAY,GAAG,MAAM,CAAC;AAE5B,KAAK,UAAU,IAAI,CAAC,OAAe,EAAE,OAAe;IAClD,MAAM,MAAM,GAAG,MAAM,GAAG,CACtB,QAAQ,EACR,CAAC,uBAAuB,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,EAC7D,EAAE,YAAY,EAAE,IAAI,EAAE,CACvB,CAAC;IACF,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CAAC,yBAAyB,OAAO,IAAI,OAAO,EAAE,CAAC,CAAC;IACjE,CAAC;IACD,IAAI,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;IAC/B,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAE,CAAC;QAAE,GAAG,IAAI,CAAC,CAAC;IAC3E,OAAO,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACxC,CAAC;AAED,KAAK,UAAU,MAAM,CAAC,OAAe,EAAE,OAAe;IACpD,MAAM,GAAG,CACP,QAAQ,EACR,CAAC,yBAAyB,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,EACzD,EAAE,YAAY,EAAE,IAAI,EAAE,CACvB,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,KAAK,CAClB,OAAe,EACf,OAAe,EACf,UAAkB,EAClB,mBAA6B;IAE7B,MAAM,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC/B,MAAM,IAAI,GAAG;QACX,sBAAsB;QACtB,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,GAAG,OAAO,IAAI,OAAO,EAAE;KAC9B,CAAC;IACF,KAAK,MAAM,WAAW,IAAI,mBAAmB,EAAE,CAAC;QAC9C,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAC/B,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,IAAI,
|
|
1
|
+
{"version":3,"file":"keychain.js","sourceRoot":"","sources":["../../src/keychain.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function maybeRunOnboarding(command: string): Promise<void>;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { loadState, saveState } from "./config.js";
|
|
2
|
+
import { installShellIntegration, shellIntegrationInstalled } from "./install.js";
|
|
3
|
+
import { run } from "./processes.js";
|
|
4
|
+
import { confirmAction } from "./ui.js";
|
|
5
|
+
const repository = "dongwook-chan/agyx";
|
|
6
|
+
async function ghInstalled() {
|
|
7
|
+
const result = await run("/bin/sh", ["-lc", "command -v gh >/dev/null 2>&1"], { allowFailure: true });
|
|
8
|
+
return result.code === 0;
|
|
9
|
+
}
|
|
10
|
+
async function promptShellIntegration() {
|
|
11
|
+
const state = await loadState();
|
|
12
|
+
if (state.onboarding?.shellIntegrationPromptedAt)
|
|
13
|
+
return;
|
|
14
|
+
if (await shellIntegrationInstalled())
|
|
15
|
+
return;
|
|
16
|
+
const now = new Date().toISOString();
|
|
17
|
+
state.onboarding = {
|
|
18
|
+
...state.onboarding,
|
|
19
|
+
shellIntegrationPromptedAt: now,
|
|
20
|
+
};
|
|
21
|
+
await saveState(state);
|
|
22
|
+
if (!await confirmAction("Install agy shell integration so `agy` runs through agyx?", true)) {
|
|
23
|
+
console.log("Skipped shell integration. You can run it later with: agyx install");
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const path = await installShellIntegration();
|
|
27
|
+
const updated = await loadState();
|
|
28
|
+
updated.onboarding = {
|
|
29
|
+
...updated.onboarding,
|
|
30
|
+
shellIntegrationInstalledAt: new Date().toISOString(),
|
|
31
|
+
};
|
|
32
|
+
await saveState(updated);
|
|
33
|
+
console.log(`Installed agy shell function in ${path}`);
|
|
34
|
+
console.log("This does not change the current terminal automatically.");
|
|
35
|
+
console.log("Open a new terminal, or run:");
|
|
36
|
+
console.log(` source ${path}`);
|
|
37
|
+
console.log("For this terminal only, you can also run:");
|
|
38
|
+
console.log(' eval "$(agyx shell-init)"');
|
|
39
|
+
console.log("Verify with:");
|
|
40
|
+
console.log(" type agy");
|
|
41
|
+
}
|
|
42
|
+
async function promptGithubStar() {
|
|
43
|
+
const state = await loadState();
|
|
44
|
+
if (state.onboarding?.githubStarPromptedAt || state.onboarding?.githubStarredAt)
|
|
45
|
+
return;
|
|
46
|
+
if (!await ghInstalled())
|
|
47
|
+
return;
|
|
48
|
+
const now = new Date().toISOString();
|
|
49
|
+
state.onboarding = {
|
|
50
|
+
...state.onboarding,
|
|
51
|
+
githubStarPromptedAt: now,
|
|
52
|
+
};
|
|
53
|
+
await saveState(state);
|
|
54
|
+
if (!await confirmAction(`Star ${repository} on GitHub with gh?`, false))
|
|
55
|
+
return;
|
|
56
|
+
try {
|
|
57
|
+
await run("/usr/bin/env", [
|
|
58
|
+
"gh",
|
|
59
|
+
"api",
|
|
60
|
+
"--method", "PUT",
|
|
61
|
+
"/user/starred/dongwook-chan/agyx",
|
|
62
|
+
"--silent",
|
|
63
|
+
]);
|
|
64
|
+
const updated = await loadState();
|
|
65
|
+
updated.onboarding = {
|
|
66
|
+
...updated.onboarding,
|
|
67
|
+
githubStarredAt: new Date().toISOString(),
|
|
68
|
+
};
|
|
69
|
+
await saveState(updated);
|
|
70
|
+
console.log(`Starred ${repository}.`);
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
console.error(`agyx: failed to star ${repository}: ${error.message}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
export async function maybeRunOnboarding(command) {
|
|
77
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY)
|
|
78
|
+
return;
|
|
79
|
+
if (process.env.AGYX_NO_ONBOARDING === "1")
|
|
80
|
+
return;
|
|
81
|
+
if (["session", "shell-init", "_activate"].includes(command))
|
|
82
|
+
return;
|
|
83
|
+
if (command !== "install")
|
|
84
|
+
await promptShellIntegration();
|
|
85
|
+
await promptGithubStar();
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=onboarding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"onboarding.js","sourceRoot":"","sources":["../../src/onboarding.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAClF,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAExC,MAAM,UAAU,GAAG,oBAAoB,CAAC;AAExC,KAAK,UAAU,WAAW;IACxB,MAAM,MAAM,GAAG,MAAM,GAAG,CACtB,SAAS,EACT,CAAC,KAAK,EAAE,+BAA+B,CAAC,EACxC,EAAE,YAAY,EAAE,IAAI,EAAE,CACvB,CAAC;IACF,OAAO,MAAM,CAAC,IAAI,KAAK,CAAC,CAAC;AAC3B,CAAC;AAED,KAAK,UAAU,sBAAsB;IACnC,MAAM,KAAK,GAAG,MAAM,SAAS,EAAE,CAAC;IAChC,IAAI,KAAK,CAAC,UAAU,EAAE,0BAA0B;QAAE,OAAO;IACzD,IAAI,MAAM,yBAAyB,EAAE;QAAE,OAAO;IAE9C,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,KAAK,CAAC,UAAU,GAAG;QACjB,GAAG,KAAK,CAAC,UAAU;QACnB,0BAA0B,EAAE,GAAG;KAChC,CAAC;IACF,MAAM,SAAS,CAAC,KAAK,CAAC,CAAC;IAEvB,IAAI,CAAC,MAAM,aAAa,CAAC,2DAA2D,EAAE,IAAI,CAAC,EAAE,CAAC;QAC5F,OAAO,CAAC,GAAG,CAAC,oEAAoE,CAAC,CAAC;QAClF,OAAO;IACT,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,uBAAuB,EAAE,CAAC;IAC7C,MAAM,OAAO,GAAG,MAAM,SAAS,EAAE,CAAC;IAClC,OAAO,CAAC,UAAU,GAAG;QACnB,GAAG,OAAO,CAAC,UAAU;QACrB,2BAA2B,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACtD,CAAC;IACF,MAAM,SAAS,CAAC,OAAO,CAAC,CAAC;IACzB,OAAO,CAAC,GAAG,CAAC,mCAAmC,IAAI,EAAE,CAAC,CAAC;IACvD,OAAO,CAAC,GAAG,CAAC,0DAA0D,CAAC,CAAC;IACxE,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;IAChC,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC5B,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;AAC5B,CAAC;AAED,KAAK,UAAU,gBAAgB;IAC7B,MAAM,KAAK,GAAG,MAAM,SAAS,EAAE,CAAC;IAChC,IAAI,KAAK,CAAC,UAAU,EAAE,oBAAoB,IAAI,KAAK,CAAC,UAAU,EAAE,eAAe;QAAE,OAAO;IACxF,IAAI,CAAC,MAAM,WAAW,EAAE;QAAE,OAAO;IAEjC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,KAAK,CAAC,UAAU,GAAG;QACjB,GAAG,KAAK,CAAC,UAAU;QACnB,oBAAoB,EAAE,GAAG;KAC1B,CAAC;IACF,MAAM,SAAS,CAAC,KAAK,CAAC,CAAC;IAEvB,IAAI,CAAC,MAAM,aAAa,CAAC,QAAQ,UAAU,qBAAqB,EAAE,KAAK,CAAC;QAAE,OAAO;IAEjF,IAAI,CAAC;QACH,MAAM,GAAG,CAAC,cAAc,EAAE;YACxB,IAAI;YACJ,KAAK;YACL,UAAU,EAAE,KAAK;YACjB,kCAAkC;YAClC,UAAU;SACX,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,SAAS,EAAE,CAAC;QAClC,OAAO,CAAC,UAAU,GAAG;YACnB,GAAG,OAAO,CAAC,UAAU;YACrB,eAAe,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SAC1C,CAAC;QACF,MAAM,SAAS,CAAC,OAAO,CAAC,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,WAAW,UAAU,GAAG,CAAC,CAAC;IACxC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,wBAAwB,UAAU,KAAM,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;IACnF,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAAe;IACtD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK;QAAE,OAAO;IAC1D,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,GAAG;QAAE,OAAO;IACnD,IAAI,CAAC,SAAS,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO;IAErE,IAAI,OAAO,KAAK,SAAS;QAAE,MAAM,sBAAsB,EAAE,CAAC;IAC1D,MAAM,gBAAgB,EAAE,CAAC;AAC3B,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ProfileRecord, State } from "./config.js";
|
|
2
|
+
import { ProfileRuntimeStatus } from "./selection.js";
|
|
3
|
+
export interface ProfileView {
|
|
4
|
+
marker: string;
|
|
5
|
+
number: string;
|
|
6
|
+
name: string;
|
|
7
|
+
expectedEmail: string;
|
|
8
|
+
actualEmail: string;
|
|
9
|
+
status: string;
|
|
10
|
+
quotaReset: string;
|
|
11
|
+
lastRequest: string;
|
|
12
|
+
activated: string;
|
|
13
|
+
verified: string;
|
|
14
|
+
switches: string;
|
|
15
|
+
selectable: boolean;
|
|
16
|
+
runtimeStatus: ProfileRuntimeStatus;
|
|
17
|
+
disabledReason?: string;
|
|
18
|
+
profile: ProfileRecord;
|
|
19
|
+
}
|
|
20
|
+
export declare function relativeTime(value: string | undefined, now?: Date): string;
|
|
21
|
+
export declare function profileStatusText(profile: ProfileRecord, now?: Date): string;
|
|
22
|
+
export declare function buildProfileViews(state: Pick<State, "activeProfile" | "profiles">, now?: Date): ProfileView[];
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { effectiveProfileStatus } from "./selection.js";
|
|
2
|
+
export function relativeTime(value, now = new Date()) {
|
|
3
|
+
if (!value)
|
|
4
|
+
return "-";
|
|
5
|
+
const timestamp = Date.parse(value);
|
|
6
|
+
if (Number.isNaN(timestamp))
|
|
7
|
+
return "-";
|
|
8
|
+
const delta = timestamp - now.getTime();
|
|
9
|
+
const absolute = Math.abs(delta);
|
|
10
|
+
const units = [
|
|
11
|
+
[24 * 60 * 60 * 1000, "d"],
|
|
12
|
+
[60 * 60 * 1000, "h"],
|
|
13
|
+
[60 * 1000, "m"],
|
|
14
|
+
[1000, "s"],
|
|
15
|
+
];
|
|
16
|
+
const [unitMs, suffix] = units.find(([ms]) => absolute >= ms) ?? units.at(-1);
|
|
17
|
+
const amount = Math.max(1, Math.round(absolute / unitMs));
|
|
18
|
+
return delta >= 0 ? `in ${amount}${suffix}` : `${amount}${suffix} ago`;
|
|
19
|
+
}
|
|
20
|
+
export function profileStatusText(profile, now = new Date()) {
|
|
21
|
+
const status = effectiveProfileStatus(profile, now);
|
|
22
|
+
if (status === "disabled")
|
|
23
|
+
return "disabled";
|
|
24
|
+
if (status === "mismatch")
|
|
25
|
+
return "mismatch";
|
|
26
|
+
if (status === "error")
|
|
27
|
+
return "auth-error";
|
|
28
|
+
if (status === "ineligible")
|
|
29
|
+
return "ineligible";
|
|
30
|
+
if (status === "exhausted")
|
|
31
|
+
return "quota";
|
|
32
|
+
return profile.quotaStatus === "available" ? "ready" : "unknown";
|
|
33
|
+
}
|
|
34
|
+
export function buildProfileViews(state, now = new Date()) {
|
|
35
|
+
return state.profiles.map((profile, index) => {
|
|
36
|
+
const runtimeStatus = effectiveProfileStatus(profile, now);
|
|
37
|
+
const disabledReason = (() => {
|
|
38
|
+
if (runtimeStatus === "ready")
|
|
39
|
+
return undefined;
|
|
40
|
+
if (runtimeStatus === "mismatch") {
|
|
41
|
+
return profile.credentialError
|
|
42
|
+
?? `expected ${profile.email ?? "-"}, got ${profile.verifiedEmail ?? "-"}`;
|
|
43
|
+
}
|
|
44
|
+
if (runtimeStatus === "error") {
|
|
45
|
+
return profile.credentialError ?? "credential could not be verified";
|
|
46
|
+
}
|
|
47
|
+
if (runtimeStatus === "ineligible") {
|
|
48
|
+
return profile.eligibilityReason
|
|
49
|
+
?? "account is not eligible for Antigravity; verify it in the browser or login another account";
|
|
50
|
+
}
|
|
51
|
+
if (runtimeStatus === "exhausted") {
|
|
52
|
+
return profile.quotaResetAt
|
|
53
|
+
? `quota resets ${relativeTime(profile.quotaResetAt, now)}`
|
|
54
|
+
: "quota exhausted";
|
|
55
|
+
}
|
|
56
|
+
return "disabled";
|
|
57
|
+
})();
|
|
58
|
+
return {
|
|
59
|
+
marker: profile.name === state.activeProfile ? "*" : "",
|
|
60
|
+
number: String(index + 1),
|
|
61
|
+
name: profile.name,
|
|
62
|
+
expectedEmail: profile.email ?? "-",
|
|
63
|
+
actualEmail: profile.verifiedEmail ?? "-",
|
|
64
|
+
status: profileStatusText(profile, now),
|
|
65
|
+
quotaReset: relativeTime(profile.quotaResetAt, now),
|
|
66
|
+
lastRequest: relativeTime(profile.lastRequestAt, now),
|
|
67
|
+
activated: relativeTime(profile.lastActivatedAt, now),
|
|
68
|
+
verified: relativeTime(profile.credentialVerifiedAt ?? profile.credentialMismatchAt, now),
|
|
69
|
+
switches: String(profile.selectionCount ?? 0),
|
|
70
|
+
selectable: runtimeStatus === "ready",
|
|
71
|
+
runtimeStatus,
|
|
72
|
+
disabledReason,
|
|
73
|
+
profile,
|
|
74
|
+
};
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=profile_view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile_view.js","sourceRoot":"","sources":["../../src/profile_view.ts"],"names":[],"mappings":"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"}
|
package/dist/src/quota.d.ts
CHANGED
package/dist/src/quota.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
export function isRequestEventLine(line) {
|
|
2
|
+
return /Sending user message to conversation [0-9a-f-]{36}/i.test(line);
|
|
3
|
+
}
|
|
1
4
|
function parseDurationMs(value) {
|
|
2
5
|
const pattern = /(\d+(?:\.\d+)?)\s*(d|day|days|h|hr|hrs|hour|hours|m|min|mins|minute|minutes|s|sec|secs|second|seconds)/gi;
|
|
3
6
|
let total = 0;
|
package/dist/src/quota.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quota.js","sourceRoot":"","sources":["../../src/quota.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"quota.js","sourceRoot":"","sources":["../../src/quota.ts"],"names":[],"mappings":"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"}
|
package/dist/src/selection.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ProfileRecord, State } from "./config.js";
|
|
2
|
-
export type ProfileRuntimeStatus = "ready" | "exhausted" | "disabled";
|
|
2
|
+
export type ProfileRuntimeStatus = "ready" | "exhausted" | "disabled" | "mismatch" | "error" | "ineligible";
|
|
3
3
|
export declare function effectiveProfileStatus(profile: ProfileRecord, now?: Date): ProfileRuntimeStatus;
|
|
4
4
|
export declare function isProfileSelectable(profile: ProfileRecord, now?: Date): boolean;
|
|
5
5
|
export declare function selectNextProfile(state: State, now?: Date): ProfileRecord;
|
package/dist/src/selection.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
export function effectiveProfileStatus(profile, now = new Date()) {
|
|
2
2
|
if (profile.disabled)
|
|
3
3
|
return "disabled";
|
|
4
|
+
if (profile.credentialStatus === "mismatch")
|
|
5
|
+
return "mismatch";
|
|
6
|
+
if (profile.credentialStatus === "error")
|
|
7
|
+
return "error";
|
|
8
|
+
if (profile.eligibilityStatus === "ineligible")
|
|
9
|
+
return "ineligible";
|
|
4
10
|
if (profile.quotaStatus !== "exhausted")
|
|
5
11
|
return "ready";
|
|
6
12
|
if (!profile.quotaResetAt)
|
|
@@ -27,9 +33,20 @@ export function selectNextProfile(state, now = new Date()) {
|
|
|
27
33
|
const earliestReset = state.profiles
|
|
28
34
|
.filter((profile) => profile.quotaResetAt)
|
|
29
35
|
.sort((left, right) => Date.parse(left.quotaResetAt) - Date.parse(right.quotaResetAt))[0];
|
|
36
|
+
const credentialIssues = state.profiles
|
|
37
|
+
.filter((profile) => profile.credentialStatus === "mismatch"
|
|
38
|
+
|| profile.credentialStatus === "error"
|
|
39
|
+
|| profile.eligibilityStatus === "ineligible")
|
|
40
|
+
.map((profile) => profile.eligibilityStatus === "ineligible"
|
|
41
|
+
? `${profile.name}:ineligible`
|
|
42
|
+
: `${profile.name}:${profile.credentialStatus}`)
|
|
43
|
+
.join(", ");
|
|
30
44
|
const resetText = earliestReset
|
|
31
45
|
? ` Earliest reset: ${earliestReset.name} at ${earliestReset.quotaResetAt}.`
|
|
32
46
|
: "";
|
|
33
|
-
|
|
47
|
+
const credentialText = credentialIssues
|
|
48
|
+
? ` Credential issues: ${credentialIssues}.`
|
|
49
|
+
: "";
|
|
50
|
+
throw new Error(`No selectable profiles.${credentialText}${resetText}`);
|
|
34
51
|
}
|
|
35
52
|
//# sourceMappingURL=selection.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selection.js","sourceRoot":"","sources":["../../src/selection.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"selection.js","sourceRoot":"","sources":["../../src/selection.ts"],"names":[],"mappings":"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"}
|
package/dist/src/session.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { createServer } from "node:net";
|
|
3
|
-
import { readFile, writeFile } from "node:fs/promises";
|
|
3
|
+
import { chmod, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
4
4
|
import { join } from "node:path";
|
|
5
|
-
import { cleanupRuntimeFile, ensureDirectories, loadState, logDir, recordProfileQuotaExhausted, runtimeDir, } from "./config.js";
|
|
5
|
+
import { cleanupRuntimeFile, ensureDirectories, loadState, logDir, recordProfileIneligible, recordProfileQuotaExhausted, recordProfileRequest, runtimeDir, } from "./config.js";
|
|
6
6
|
import { findRealAgy, isRestartable, withConversation, } from "./processes.js";
|
|
7
|
-
import {
|
|
7
|
+
import { parseEligibilityEventLine } from "./eligibility.js";
|
|
8
|
+
import { isRequestEventLine, parseQuotaEventLine } from "./quota.js";
|
|
8
9
|
export function detectConversation(content) {
|
|
9
10
|
const patterns = [
|
|
10
11
|
/Created conversation ([0-9a-f-]{36})/gi,
|
|
@@ -38,30 +39,44 @@ export async function supervise(args) {
|
|
|
38
39
|
const recordPath = join(runtimeDir, `${id}.json`);
|
|
39
40
|
const logPath = join(logDir, `session-${id}.log`);
|
|
40
41
|
const realAgy = await findRealAgy();
|
|
42
|
+
const startedAt = new Date().toISOString();
|
|
41
43
|
let child;
|
|
42
44
|
let paused = false;
|
|
43
45
|
let intentionalStop = false;
|
|
44
46
|
let conversationId;
|
|
45
47
|
let finalCode = 0;
|
|
46
48
|
let logOffset = 0;
|
|
47
|
-
let
|
|
49
|
+
let scanningLogEvents = false;
|
|
48
50
|
let profileAtStart;
|
|
51
|
+
let quotaMarked = false;
|
|
49
52
|
let quotaInterval;
|
|
53
|
+
let persistCount = 0;
|
|
54
|
+
const currentRecord = () => ({
|
|
55
|
+
id,
|
|
56
|
+
pid: process.pid,
|
|
57
|
+
childPid: child?.pid,
|
|
58
|
+
cwd: process.cwd(),
|
|
59
|
+
args,
|
|
60
|
+
conversationId,
|
|
61
|
+
socketPath,
|
|
62
|
+
logPath,
|
|
63
|
+
paused,
|
|
64
|
+
restartable: true,
|
|
65
|
+
startedAt,
|
|
66
|
+
});
|
|
50
67
|
const persist = async () => {
|
|
51
|
-
const record =
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
};
|
|
64
|
-
await writeFile(recordPath, `${JSON.stringify(record, null, 2)}\n`, { mode: 0o600 });
|
|
68
|
+
const record = currentRecord();
|
|
69
|
+
const temporary = `${recordPath}.${process.pid}.${persistCount++}.tmp`;
|
|
70
|
+
try {
|
|
71
|
+
await writeFile(temporary, `${JSON.stringify(record, null, 2)}\n`, { mode: 0o600 });
|
|
72
|
+
await chmod(temporary, 0o600);
|
|
73
|
+
await rename(temporary, recordPath);
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
await rm(temporary, { force: true }).catch(() => undefined);
|
|
77
|
+
throw error;
|
|
78
|
+
}
|
|
79
|
+
return record;
|
|
65
80
|
};
|
|
66
81
|
const refreshConversation = async () => {
|
|
67
82
|
try {
|
|
@@ -72,10 +87,10 @@ export async function supervise(args) {
|
|
|
72
87
|
// The log may not exist until agy has initialized.
|
|
73
88
|
}
|
|
74
89
|
};
|
|
75
|
-
const
|
|
76
|
-
if (
|
|
90
|
+
const scanLogEvents = async () => {
|
|
91
|
+
if (scanningLogEvents)
|
|
77
92
|
return;
|
|
78
|
-
|
|
93
|
+
scanningLogEvents = true;
|
|
79
94
|
try {
|
|
80
95
|
const profileName = profileAtStart;
|
|
81
96
|
if (!profileName)
|
|
@@ -86,26 +101,34 @@ export async function supervise(args) {
|
|
|
86
101
|
const appended = content.slice(logOffset);
|
|
87
102
|
logOffset = content.length;
|
|
88
103
|
for (const line of appended.split(/\r?\n/)) {
|
|
104
|
+
if (isRequestEventLine(line)) {
|
|
105
|
+
await recordProfileRequest(profileName);
|
|
106
|
+
}
|
|
107
|
+
const eligibilityEvent = parseEligibilityEventLine(line);
|
|
108
|
+
if (eligibilityEvent) {
|
|
109
|
+
await recordProfileIneligible(profileName, eligibilityEvent);
|
|
110
|
+
}
|
|
89
111
|
const event = parseQuotaEventLine(line);
|
|
90
112
|
if (!event)
|
|
91
113
|
continue;
|
|
114
|
+
if (quotaMarked)
|
|
115
|
+
continue;
|
|
116
|
+
quotaMarked = true;
|
|
92
117
|
await recordProfileQuotaExhausted(profileName, event);
|
|
93
|
-
console.error(`agyx: marked profile '${profileName}' as quota exhausted`
|
|
94
|
-
+ (event.resetAt ? ` until ${event.resetAt}` : "")
|
|
95
|
-
+ ". Run 'agyx next' to switch.");
|
|
96
118
|
}
|
|
97
119
|
}
|
|
98
120
|
catch {
|
|
99
121
|
// The log or state file may not exist yet.
|
|
100
122
|
}
|
|
101
123
|
finally {
|
|
102
|
-
|
|
124
|
+
scanningLogEvents = false;
|
|
103
125
|
}
|
|
104
126
|
};
|
|
105
127
|
const startChild = async () => {
|
|
106
128
|
intentionalStop = false;
|
|
107
129
|
paused = false;
|
|
108
130
|
profileAtStart = (await loadState()).activeProfile;
|
|
131
|
+
quotaMarked = false;
|
|
109
132
|
const launchArgs = withConversation(args, conversationId);
|
|
110
133
|
if (!launchArgs.some((argument) => argument === "--log-file" || argument.startsWith("--log-file="))) {
|
|
111
134
|
launchArgs.push("--log-file", logPath);
|
|
@@ -123,7 +146,7 @@ export async function supervise(args) {
|
|
|
123
146
|
child.on("exit", async (code, signal) => {
|
|
124
147
|
finalCode = code ?? (signal ? 128 : 1);
|
|
125
148
|
await refreshConversation();
|
|
126
|
-
await
|
|
149
|
+
await scanLogEvents();
|
|
127
150
|
child = undefined;
|
|
128
151
|
await persist();
|
|
129
152
|
if (!intentionalStop && !paused) {
|
|
@@ -163,8 +186,8 @@ export async function supervise(args) {
|
|
|
163
186
|
if (request.command === "pause") {
|
|
164
187
|
paused = true;
|
|
165
188
|
await stopChild();
|
|
166
|
-
await persist();
|
|
167
|
-
writeJSON(socket, { ok: true, record
|
|
189
|
+
const record = await persist();
|
|
190
|
+
writeJSON(socket, { ok: true, record });
|
|
168
191
|
}
|
|
169
192
|
else if (request.command === "resume") {
|
|
170
193
|
if (!child)
|
|
@@ -179,8 +202,8 @@ export async function supervise(args) {
|
|
|
179
202
|
}
|
|
180
203
|
else {
|
|
181
204
|
await refreshConversation();
|
|
182
|
-
await persist();
|
|
183
|
-
writeJSON(socket, { ok: true, record
|
|
205
|
+
const record = await persist();
|
|
206
|
+
writeJSON(socket, { ok: true, record });
|
|
184
207
|
}
|
|
185
208
|
}
|
|
186
209
|
catch (error) {
|
|
@@ -212,7 +235,7 @@ export async function supervise(args) {
|
|
|
212
235
|
});
|
|
213
236
|
await startChild();
|
|
214
237
|
quotaInterval = setInterval(() => {
|
|
215
|
-
void
|
|
238
|
+
void scanLogEvents();
|
|
216
239
|
}, 750);
|
|
217
240
|
quotaInterval.unref();
|
|
218
241
|
return await new Promise(() => undefined);
|