crewly 1.20.172 → 1.20.174
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/backend/backend/src/constants.d.ts +38 -1
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +41 -1
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +34 -2
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.js +17 -2
- package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.js.map +1 -1
- package/dist/backend/backend/src/services/harness/harness-exec.utils.d.ts.map +1 -1
- package/dist/backend/backend/src/services/harness/harness-exec.utils.js +1 -0
- package/dist/backend/backend/src/services/harness/harness-exec.utils.js.map +1 -1
- package/dist/backend/backend/src/services/harness/harness-login-probe.d.ts +65 -0
- package/dist/backend/backend/src/services/harness/harness-login-probe.d.ts.map +1 -0
- package/dist/backend/backend/src/services/harness/harness-login-probe.js +99 -0
- package/dist/backend/backend/src/services/harness/harness-login-probe.js.map +1 -0
- package/dist/backend/backend/src/services/harness/harness-relogin.service.d.ts +349 -113
- package/dist/backend/backend/src/services/harness/harness-relogin.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/harness/harness-relogin.service.js +792 -278
- package/dist/backend/backend/src/services/harness/harness-relogin.service.js.map +1 -1
- package/dist/backend/backend/src/services/harness/harness.types.d.ts +2 -0
- package/dist/backend/backend/src/services/harness/harness.types.d.ts.map +1 -1
- package/dist/backend/backend/src/services/harness/login-broker.service.d.ts +6 -0
- package/dist/backend/backend/src/services/harness/login-broker.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/harness/login-broker.service.js +32 -1
- package/dist/backend/backend/src/services/harness/login-broker.service.js.map +1 -1
- package/dist/backend/backend/src/services/harness/relogin-state.store.d.ts +61 -0
- package/dist/backend/backend/src/services/harness/relogin-state.store.d.ts.map +1 -0
- package/dist/backend/backend/src/services/harness/relogin-state.store.js +92 -0
- package/dist/backend/backend/src/services/harness/relogin-state.store.js.map +1 -0
- package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.d.ts +26 -1
- package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.js +77 -2
- package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-relogin-dm.service.d.ts +42 -19
- package/dist/backend/backend/src/services/slack/slack-relogin-dm.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-relogin-dm.service.js +69 -31
- package/dist/backend/backend/src/services/slack/slack-relogin-dm.service.js.map +1 -1
- package/dist/backend/backend/src/services/v3/request-status-update.subscriber.d.ts +1 -1
- package/dist/backend/backend/src/services/v3/request-status-update.subscriber.js +15 -15
- package/dist/backend/backend/src/services/v3/request-status-update.subscriber.js.map +1 -1
- package/dist/backend/build-info.json +2 -2
- package/dist/cli/backend/src/constants.d.ts +38 -1
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +41 -1
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.js +17 -2
- package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.js.map +1 -1
- package/dist/cli/backend/src/services/harness/harness-exec.utils.d.ts.map +1 -1
- package/dist/cli/backend/src/services/harness/harness-exec.utils.js +1 -0
- package/dist/cli/backend/src/services/harness/harness-exec.utils.js.map +1 -1
- package/dist/cli/backend/src/services/harness/harness-login-probe.d.ts +65 -0
- package/dist/cli/backend/src/services/harness/harness-login-probe.d.ts.map +1 -0
- package/dist/cli/backend/src/services/harness/harness-login-probe.js +99 -0
- package/dist/cli/backend/src/services/harness/harness-login-probe.js.map +1 -0
- package/dist/cli/backend/src/services/harness/harness-relogin.service.d.ts +349 -113
- package/dist/cli/backend/src/services/harness/harness-relogin.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/harness/harness-relogin.service.js +792 -278
- package/dist/cli/backend/src/services/harness/harness-relogin.service.js.map +1 -1
- package/dist/cli/backend/src/services/harness/harness.types.d.ts +2 -0
- package/dist/cli/backend/src/services/harness/harness.types.d.ts.map +1 -1
- package/dist/cli/backend/src/services/harness/login-broker.service.d.ts +6 -0
- package/dist/cli/backend/src/services/harness/login-broker.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/harness/login-broker.service.js +32 -1
- package/dist/cli/backend/src/services/harness/login-broker.service.js.map +1 -1
- package/dist/cli/backend/src/services/harness/relogin-state.store.d.ts +61 -0
- package/dist/cli/backend/src/services/harness/relogin-state.store.d.ts.map +1 -0
- package/dist/cli/backend/src/services/harness/relogin-state.store.js +92 -0
- package/dist/cli/backend/src/services/harness/relogin-state.store.js.map +1 -0
- package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.d.ts +26 -1
- package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.js +77 -2
- package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.js.map +1 -1
- package/frontend/dist/assets/{index-cb23748e.js → index-36e85ac8.js} +258 -258
- package/frontend/dist/index.html +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live sign-in probe — is a harness's login actually usable right now?
|
|
3
|
+
*
|
|
4
|
+
* The status checks in {@link HarnessStatusService} only see whether a
|
|
5
|
+
* credential is *stored*. For Claude Code that is not enough: an expired or
|
|
6
|
+
* revoked login stays in the macOS keychain (and `claude auth status` keeps
|
|
7
|
+
* saying `loggedIn: true`), so a machine whose every agent sits at
|
|
8
|
+
* "Login expired · Please run /login" still looks logged in. The re-login
|
|
9
|
+
* coordinator therefore confirms a suspected expiry with this probe before
|
|
10
|
+
* telling the owner, and runs it now and then for harnesses in use so an
|
|
11
|
+
* expiry is noticed even when no agent is running (the Air, 2026-09-30).
|
|
12
|
+
*
|
|
13
|
+
* - Claude Code: one tiny print-mode turn (`claude -p … --model haiku
|
|
14
|
+
* --no-session-persistence`) in a scratch directory, with the env agents
|
|
15
|
+
* get (a token Crewly stores is used, exactly as an agent would). Exit 0 →
|
|
16
|
+
* `logged_in`; output that matches a login-expiry rule → `logged_out`;
|
|
17
|
+
* anything else (network, rate limit, timeout) → `unknown`.
|
|
18
|
+
* - Codex: `codex login status` (what the status check already asks).
|
|
19
|
+
*
|
|
20
|
+
* The probe never logs in or out and never prints a secret.
|
|
21
|
+
*
|
|
22
|
+
* @module services/harness/harness-login-probe
|
|
23
|
+
*/
|
|
24
|
+
import { type HarnessCredentialsStore } from './harness-credentials.store.js';
|
|
25
|
+
import type { HarnessId, LoginState, RunCommand } from './harness.types.js';
|
|
26
|
+
/** Injectable dependencies. */
|
|
27
|
+
export interface HarnessLoginProbeDeps {
|
|
28
|
+
run?: RunCommand;
|
|
29
|
+
/** Base env (default process.env) */
|
|
30
|
+
env?: NodeJS.ProcessEnv;
|
|
31
|
+
homeDir?: string;
|
|
32
|
+
/** PATH lookup of the harness binary */
|
|
33
|
+
resolveCommand?: (command: string) => string | null;
|
|
34
|
+
/** Stored credentials exported to agents (Claude token / key) */
|
|
35
|
+
credentials?: Pick<HarnessCredentialsStore, 'harnessEnvForAgents'>;
|
|
36
|
+
/** Scratch directory the Claude probe runs in */
|
|
37
|
+
scratchDir?: string;
|
|
38
|
+
timeoutMs?: number;
|
|
39
|
+
}
|
|
40
|
+
/** Result of one probe. */
|
|
41
|
+
export type HarnessLoginProbe = (harnessId: HarnessId) => Promise<LoginState>;
|
|
42
|
+
/**
|
|
43
|
+
* Classify the output of a Claude probe turn.
|
|
44
|
+
*
|
|
45
|
+
* @param result - Exit code and output
|
|
46
|
+
* @returns The login state it proves
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```ts
|
|
50
|
+
* classifyClaudeProbe({ code: 1, stdout: 'Not logged in · Please run /login', stderr: '' }); // 'logged_out'
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export declare function classifyClaudeProbe(result: {
|
|
54
|
+
code: number | null;
|
|
55
|
+
stdout: string;
|
|
56
|
+
stderr: string;
|
|
57
|
+
}): LoginState;
|
|
58
|
+
/**
|
|
59
|
+
* Build the probe.
|
|
60
|
+
*
|
|
61
|
+
* @param deps - Dependencies (defaults: the real CLI and stored credentials)
|
|
62
|
+
* @returns `probe(harnessId)` → `logged_in` / `logged_out` / `unknown`; never rejects
|
|
63
|
+
*/
|
|
64
|
+
export declare function createHarnessLoginProbe(deps?: HarnessLoginProbeDeps): HarnessLoginProbe;
|
|
65
|
+
//# sourceMappingURL=harness-login-probe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness-login-probe.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/harness/harness-login-probe.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAMH,OAAO,EAA8B,KAAK,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAE1G,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAG5E,+BAA+B;AAC/B,MAAM,WAAW,qBAAqB;IACrC,GAAG,CAAC,EAAE,UAAU,CAAC;IACjB,qCAAqC;IACrC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wCAAwC;IACxC,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IACpD,iEAAiE;IACjE,WAAW,CAAC,EAAE,IAAI,CAAC,uBAAuB,EAAE,qBAAqB,CAAC,CAAC;IACnE,iDAAiD;IACjD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,2BAA2B;AAC3B,MAAM,MAAM,iBAAiB,GAAG,CAAC,SAAS,EAAE,SAAS,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;AAK9E;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,UAAU,CAK/G;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,GAAE,qBAA0B,GAAG,iBAAiB,CAqC3F"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live sign-in probe — is a harness's login actually usable right now?
|
|
3
|
+
*
|
|
4
|
+
* The status checks in {@link HarnessStatusService} only see whether a
|
|
5
|
+
* credential is *stored*. For Claude Code that is not enough: an expired or
|
|
6
|
+
* revoked login stays in the macOS keychain (and `claude auth status` keeps
|
|
7
|
+
* saying `loggedIn: true`), so a machine whose every agent sits at
|
|
8
|
+
* "Login expired · Please run /login" still looks logged in. The re-login
|
|
9
|
+
* coordinator therefore confirms a suspected expiry with this probe before
|
|
10
|
+
* telling the owner, and runs it now and then for harnesses in use so an
|
|
11
|
+
* expiry is noticed even when no agent is running (the Air, 2026-09-30).
|
|
12
|
+
*
|
|
13
|
+
* - Claude Code: one tiny print-mode turn (`claude -p … --model haiku
|
|
14
|
+
* --no-session-persistence`) in a scratch directory, with the env agents
|
|
15
|
+
* get (a token Crewly stores is used, exactly as an agent would). Exit 0 →
|
|
16
|
+
* `logged_in`; output that matches a login-expiry rule → `logged_out`;
|
|
17
|
+
* anything else (network, rate limit, timeout) → `unknown`.
|
|
18
|
+
* - Codex: `codex login status` (what the status check already asks).
|
|
19
|
+
*
|
|
20
|
+
* The probe never logs in or out and never prints a secret.
|
|
21
|
+
*
|
|
22
|
+
* @module services/harness/harness-login-probe
|
|
23
|
+
*/
|
|
24
|
+
import * as fs from 'fs';
|
|
25
|
+
import * as os from 'os';
|
|
26
|
+
import * as path from 'path';
|
|
27
|
+
import { HARNESS_CONSTANTS } from '../../constants.js';
|
|
28
|
+
import { getHarnessCredentialsStore } from './harness-credentials.store.js';
|
|
29
|
+
import { buildHarnessPath, resolveExecutable, runCommand } from './harness-exec.utils.js';
|
|
30
|
+
import { detectLoginExpiry } from './login-expiry-rules.js';
|
|
31
|
+
/** Env variables that would make the probe a nested Claude session or leak Crewly's API token. */
|
|
32
|
+
const STRIPPED_ENV = ['CREWLY_API_TOKEN', 'CLAUDECODE', 'CLAUDE_CODE_ENTRYPOINT', 'CLAUDE_CODE_SSE_PORT'];
|
|
33
|
+
/**
|
|
34
|
+
* Classify the output of a Claude probe turn.
|
|
35
|
+
*
|
|
36
|
+
* @param result - Exit code and output
|
|
37
|
+
* @returns The login state it proves
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* classifyClaudeProbe({ code: 1, stdout: 'Not logged in · Please run /login', stderr: '' }); // 'logged_out'
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export function classifyClaudeProbe(result) {
|
|
45
|
+
const output = `${result.stdout}\n${result.stderr}`;
|
|
46
|
+
if (detectLoginExpiry(output, HARNESS_CONSTANTS.IDS.CLAUDE_CODE))
|
|
47
|
+
return 'logged_out';
|
|
48
|
+
if (result.code === 0)
|
|
49
|
+
return 'logged_in';
|
|
50
|
+
return 'unknown';
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Build the probe.
|
|
54
|
+
*
|
|
55
|
+
* @param deps - Dependencies (defaults: the real CLI and stored credentials)
|
|
56
|
+
* @returns `probe(harnessId)` → `logged_in` / `logged_out` / `unknown`; never rejects
|
|
57
|
+
*/
|
|
58
|
+
export function createHarnessLoginProbe(deps = {}) {
|
|
59
|
+
const run = deps.run ?? runCommand;
|
|
60
|
+
const baseEnv = deps.env ?? process.env;
|
|
61
|
+
const homeDir = deps.homeDir ?? os.homedir();
|
|
62
|
+
const timeoutMs = deps.timeoutMs ?? HARNESS_CONSTANTS.RELOGIN.PROBE_TIMEOUT_MS;
|
|
63
|
+
const resolve = deps.resolveCommand ?? ((command) => resolveExecutable(command, buildHarnessPath(baseEnv.PATH, homeDir)));
|
|
64
|
+
/** Env of the probe: what an agent of that harness gets. */
|
|
65
|
+
const envFor = (harnessId) => {
|
|
66
|
+
const credentials = deps.credentials ?? getHarnessCredentialsStore();
|
|
67
|
+
const env = { ...baseEnv, ...credentials.harnessEnvForAgents(baseEnv, harnessId) };
|
|
68
|
+
for (const name of STRIPPED_ENV)
|
|
69
|
+
delete env[name];
|
|
70
|
+
return env;
|
|
71
|
+
};
|
|
72
|
+
return async (harnessId) => {
|
|
73
|
+
try {
|
|
74
|
+
if (harnessId === HARNESS_CONSTANTS.IDS.CLAUDE_CODE) {
|
|
75
|
+
const binary = resolve('claude');
|
|
76
|
+
if (!binary)
|
|
77
|
+
return 'unknown';
|
|
78
|
+
const scratch = deps.scratchDir ?? path.join(os.tmpdir(), 'crewly-login-probe');
|
|
79
|
+
fs.mkdirSync(scratch, { recursive: true });
|
|
80
|
+
const result = await run(binary, HARNESS_CONSTANTS.CLAUDE.PROBE_ARGS, { env: envFor(harnessId), timeoutMs, cwd: scratch });
|
|
81
|
+
return classifyClaudeProbe(result);
|
|
82
|
+
}
|
|
83
|
+
if (harnessId === HARNESS_CONSTANTS.IDS.CODEX_CLI) {
|
|
84
|
+
const binary = resolve('codex');
|
|
85
|
+
if (!binary)
|
|
86
|
+
return 'unknown';
|
|
87
|
+
const result = await run(binary, ['login', 'status'], { env: envFor(harnessId), timeoutMs: HARNESS_CONSTANTS.PROBE_TIMEOUT_MS });
|
|
88
|
+
if (result.code === 0)
|
|
89
|
+
return 'logged_in';
|
|
90
|
+
return result.code === null ? 'unknown' : 'logged_out';
|
|
91
|
+
}
|
|
92
|
+
return 'unknown';
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
return 'unknown';
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=harness-login-probe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness-login-probe.js","sourceRoot":"","sources":["../../../../../../backend/src/services/harness/harness-login-probe.ts"],"names":[],"mappings":"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"}
|