@namzu/cli 0.6.0 → 0.7.0
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/__tests__/permission-rules-reach-the-turn.test.d.ts +31 -0
- package/dist/__tests__/permission-rules-reach-the-turn.test.d.ts.map +1 -0
- package/dist/__tests__/permission-rules-reach-the-turn.test.js +132 -0
- package/dist/__tests__/permission-rules-reach-the-turn.test.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +16 -3
- package/dist/cli.js.map +1 -1
- package/dist/cli.test.js +7 -1
- package/dist/cli.test.js.map +1 -1
- package/dist/commands/__tests__/run-flags.test.js +0 -1
- package/dist/commands/__tests__/run-flags.test.js.map +1 -1
- package/dist/commands/__tests__/run-stream-flags.test.js +0 -1
- package/dist/commands/__tests__/run-stream-flags.test.js.map +1 -1
- package/dist/commands/run-stream.d.ts +3 -3
- package/dist/commands/run-stream.js +3 -3
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +4 -0
- package/dist/commands/run.js.map +1 -1
- package/dist/commands/stubs.d.ts +10 -0
- package/dist/commands/stubs.d.ts.map +1 -1
- package/dist/commands/stubs.js +12 -2
- package/dist/commands/stubs.js.map +1 -1
- package/dist/config/load.d.ts.map +1 -1
- package/dist/config/load.js +20 -4
- package/dist/config/load.js.map +1 -1
- package/dist/config/schema.d.ts +0 -12
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js.map +1 -1
- package/dist/doctor/checks/credentials.d.ts +20 -0
- package/dist/doctor/checks/credentials.d.ts.map +1 -0
- package/dist/doctor/checks/credentials.js +58 -0
- package/dist/doctor/checks/credentials.js.map +1 -0
- package/dist/doctor/checks/credentials.test.d.ts +10 -0
- package/dist/doctor/checks/credentials.test.d.ts.map +1 -0
- package/dist/doctor/checks/credentials.test.js +47 -0
- package/dist/doctor/checks/credentials.test.js.map +1 -0
- package/dist/doctor/checks/index.d.ts +2 -1
- package/dist/doctor/checks/index.d.ts.map +1 -1
- package/dist/doctor/checks/index.js +3 -1
- package/dist/doctor/checks/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/integrations/providers/discover.d.ts +3 -8
- package/dist/integrations/providers/discover.d.ts.map +1 -1
- package/dist/integrations/providers/discover.js +2 -12
- package/dist/integrations/providers/discover.js.map +1 -1
- package/dist/integrations/providers/discover.test.js +1 -28
- package/dist/integrations/providers/discover.test.js.map +1 -1
- package/dist/integrations/providers/index.d.ts +0 -1
- package/dist/integrations/providers/index.d.ts.map +1 -1
- package/dist/integrations/providers/index.js +0 -1
- package/dist/integrations/providers/index.js.map +1 -1
- package/dist/integrations/providers/oauth.d.ts +1 -1
- package/dist/integrations/providers/oauth.js +1 -1
- package/dist/integrations/providers/preferences.d.ts +2 -2
- package/dist/integrations/providers/preferences.js +2 -2
- package/dist/integrations/sessions/store.js +1 -1
- package/dist/integrations/sessions/store.js.map +1 -1
- package/dist/integrations/updates.d.ts +4 -12
- package/dist/integrations/updates.d.ts.map +1 -1
- package/dist/integrations/updates.js +6 -53
- package/dist/integrations/updates.js.map +1 -1
- package/dist/tui/App.d.ts.map +1 -1
- package/dist/tui/App.js +23 -131
- package/dist/tui/App.js.map +1 -1
- package/dist/tui/Picker.d.ts +4 -4
- package/dist/tui/Picker.d.ts.map +1 -1
- package/dist/tui/Picker.js +6 -8
- package/dist/tui/Picker.js.map +1 -1
- package/dist/tui/__tests__/deferred-tool-discovery.test.d.ts +24 -0
- package/dist/tui/__tests__/deferred-tool-discovery.test.d.ts.map +1 -0
- package/dist/tui/__tests__/deferred-tool-discovery.test.js +111 -0
- package/dist/tui/__tests__/deferred-tool-discovery.test.js.map +1 -0
- package/dist/tui/__tests__/to-agent-event.test.js +88 -0
- package/dist/tui/__tests__/to-agent-event.test.js.map +1 -1
- package/dist/tui/__tests__/working-directory.test.js +0 -6
- package/dist/tui/__tests__/working-directory.test.js.map +1 -1
- package/dist/tui/agent.d.ts +16 -2
- package/dist/tui/agent.d.ts.map +1 -1
- package/dist/tui/agent.js +83 -30
- package/dist/tui/agent.js.map +1 -1
- package/dist/tui/slashCommands.d.ts +0 -6
- package/dist/tui/slashCommands.d.ts.map +1 -1
- package/dist/tui/slashCommands.js +1 -21
- package/dist/tui/slashCommands.js.map +1 -1
- package/dist/tui/types.d.ts +12 -0
- package/dist/tui/types.d.ts.map +1 -1
- package/package.json +4 -5
- package/dist/commands/tools.d.ts +0 -16
- package/dist/commands/tools.d.ts.map +0 -1
- package/dist/commands/tools.js +0 -161
- package/dist/commands/tools.js.map +0 -1
- package/dist/integrations/clawtool/agents.d.ts +0 -31
- package/dist/integrations/clawtool/agents.d.ts.map +0 -1
- package/dist/integrations/clawtool/agents.js +0 -30
- package/dist/integrations/clawtool/agents.js.map +0 -1
- package/dist/integrations/clawtool/agents.test.d.ts +0 -2
- package/dist/integrations/clawtool/agents.test.d.ts.map +0 -1
- package/dist/integrations/clawtool/agents.test.js +0 -79
- package/dist/integrations/clawtool/agents.test.js.map +0 -1
- package/dist/integrations/clawtool/auth.d.ts +0 -26
- package/dist/integrations/clawtool/auth.d.ts.map +0 -1
- package/dist/integrations/clawtool/auth.js +0 -56
- package/dist/integrations/clawtool/auth.js.map +0 -1
- package/dist/integrations/clawtool/auth.test.d.ts +0 -2
- package/dist/integrations/clawtool/auth.test.d.ts.map +0 -1
- package/dist/integrations/clawtool/auth.test.js +0 -40
- package/dist/integrations/clawtool/auth.test.js.map +0 -1
- package/dist/integrations/clawtool/binary.d.ts +0 -25
- package/dist/integrations/clawtool/binary.d.ts.map +0 -1
- package/dist/integrations/clawtool/binary.js +0 -50
- package/dist/integrations/clawtool/binary.js.map +0 -1
- package/dist/integrations/clawtool/binary.test.d.ts +0 -2
- package/dist/integrations/clawtool/binary.test.d.ts.map +0 -1
- package/dist/integrations/clawtool/binary.test.js +0 -50
- package/dist/integrations/clawtool/binary.test.js.map +0 -1
- package/dist/integrations/clawtool/daemon.d.ts +0 -37
- package/dist/integrations/clawtool/daemon.d.ts.map +0 -1
- package/dist/integrations/clawtool/daemon.js +0 -109
- package/dist/integrations/clawtool/daemon.js.map +0 -1
- package/dist/integrations/clawtool/daemon.test.d.ts +0 -11
- package/dist/integrations/clawtool/daemon.test.d.ts.map +0 -1
- package/dist/integrations/clawtool/daemon.test.js +0 -118
- package/dist/integrations/clawtool/daemon.test.js.map +0 -1
- package/dist/integrations/clawtool/dispatch.d.ts +0 -33
- package/dist/integrations/clawtool/dispatch.d.ts.map +0 -1
- package/dist/integrations/clawtool/dispatch.js +0 -155
- package/dist/integrations/clawtool/dispatch.js.map +0 -1
- package/dist/integrations/clawtool/dispatch.test.d.ts +0 -2
- package/dist/integrations/clawtool/dispatch.test.d.ts.map +0 -1
- package/dist/integrations/clawtool/dispatch.test.js +0 -138
- package/dist/integrations/clawtool/dispatch.test.js.map +0 -1
- package/dist/integrations/clawtool/index.d.ts +0 -11
- package/dist/integrations/clawtool/index.d.ts.map +0 -1
- package/dist/integrations/clawtool/index.js +0 -10
- package/dist/integrations/clawtool/index.js.map +0 -1
- package/dist/integrations/clawtool/mcp.d.ts +0 -51
- package/dist/integrations/clawtool/mcp.d.ts.map +0 -1
- package/dist/integrations/clawtool/mcp.js +0 -174
- package/dist/integrations/clawtool/mcp.js.map +0 -1
- package/dist/integrations/clawtool/mcp.test.d.ts +0 -2
- package/dist/integrations/clawtool/mcp.test.d.ts.map +0 -1
- package/dist/integrations/clawtool/mcp.test.js +0 -126
- package/dist/integrations/clawtool/mcp.test.js.map +0 -1
- package/dist/integrations/clawtool/paths.d.ts +0 -8
- package/dist/integrations/clawtool/paths.d.ts.map +0 -1
- package/dist/integrations/clawtool/paths.js +0 -19
- package/dist/integrations/clawtool/paths.js.map +0 -1
- package/dist/integrations/clawtool/peers.d.ts +0 -67
- package/dist/integrations/clawtool/peers.d.ts.map +0 -1
- package/dist/integrations/clawtool/peers.js +0 -150
- package/dist/integrations/clawtool/peers.js.map +0 -1
- package/dist/integrations/clawtool/plugin.d.ts +0 -42
- package/dist/integrations/clawtool/plugin.d.ts.map +0 -1
- package/dist/integrations/clawtool/plugin.js +0 -38
- package/dist/integrations/clawtool/plugin.js.map +0 -1
- package/dist/integrations/clawtool/state.d.ts +0 -11
- package/dist/integrations/clawtool/state.d.ts.map +0 -1
- package/dist/integrations/clawtool/state.js +0 -41
- package/dist/integrations/clawtool/state.js.map +0 -1
- package/dist/integrations/clawtool/state.test.d.ts +0 -2
- package/dist/integrations/clawtool/state.test.d.ts.map +0 -1
- package/dist/integrations/clawtool/state.test.js +0 -38
- package/dist/integrations/clawtool/state.test.js.map +0 -1
- package/dist/integrations/clawtool/tooling.d.ts +0 -52
- package/dist/integrations/clawtool/tooling.d.ts.map +0 -1
- package/dist/integrations/clawtool/tooling.js +0 -91
- package/dist/integrations/clawtool/tooling.js.map +0 -1
- package/dist/integrations/clawtool/tooling.test.d.ts +0 -2
- package/dist/integrations/clawtool/tooling.test.d.ts.map +0 -1
- package/dist/integrations/clawtool/tooling.test.js +0 -58
- package/dist/integrations/clawtool/tooling.test.js.map +0 -1
- package/dist/integrations/clawtool/types.d.ts +0 -41
- package/dist/integrations/clawtool/types.d.ts.map +0 -1
- package/dist/integrations/clawtool/types.js +0 -9
- package/dist/integrations/clawtool/types.js.map +0 -1
- package/dist/integrations/providers/secrets.d.ts +0 -37
- package/dist/integrations/providers/secrets.d.ts.map +0 -1
- package/dist/integrations/providers/secrets.js +0 -69
- package/dist/integrations/providers/secrets.js.map +0 -1
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Read and trim the bearer token clawtool writes for HTTP auth.
|
|
3
|
-
*
|
|
4
|
-
* Token format: 64 hex characters (32 bytes of `crypto/rand`), newline-
|
|
5
|
-
* terminated, mode 0600 — generated by `internal/server/http.go:362-366`.
|
|
6
|
-
* `strings.TrimSpace` is applied server-side at parse time, so leading /
|
|
7
|
-
* trailing whitespace is tolerated. We mirror that here for parity.
|
|
8
|
-
*
|
|
9
|
-
* Throws `ClawtoolAuthError` if the file is missing or empty; callers
|
|
10
|
-
* should surface an actionable message ("daemon not running? run
|
|
11
|
-
* `clawtool daemon start`"). Override `path` for tests.
|
|
12
|
-
*/
|
|
13
|
-
export declare class ClawtoolAuthError extends Error {
|
|
14
|
-
readonly cause?: unknown | undefined;
|
|
15
|
-
constructor(message: string, cause?: unknown | undefined);
|
|
16
|
-
}
|
|
17
|
-
export declare function readToken(path?: string): string;
|
|
18
|
-
/**
|
|
19
|
-
* Non-throwing variant. Returns `null` if the token file is missing or
|
|
20
|
-
* empty — which is the expected case when the daemon is running in
|
|
21
|
-
* `--no-auth` mode (single-user loopback). Callers in that path should
|
|
22
|
-
* proceed with no bearer header; clawtool ignores `Authorization` when
|
|
23
|
-
* no-auth is on.
|
|
24
|
-
*/
|
|
25
|
-
export declare function tryReadToken(path?: string): string | null;
|
|
26
|
-
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/integrations/clawtool/auth.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAG1C,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO;gBADxB,OAAO,EAAE,MAAM,EACN,KAAK,CAAC,EAAE,OAAO,YAAA;CAKzB;AAED,wBAAgB,SAAS,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAgB/C;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CASzD"}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { readFileSync } from 'node:fs';
|
|
2
|
-
import { listenerTokenPath } from './paths.js';
|
|
3
|
-
/**
|
|
4
|
-
* Read and trim the bearer token clawtool writes for HTTP auth.
|
|
5
|
-
*
|
|
6
|
-
* Token format: 64 hex characters (32 bytes of `crypto/rand`), newline-
|
|
7
|
-
* terminated, mode 0600 — generated by `internal/server/http.go:362-366`.
|
|
8
|
-
* `strings.TrimSpace` is applied server-side at parse time, so leading /
|
|
9
|
-
* trailing whitespace is tolerated. We mirror that here for parity.
|
|
10
|
-
*
|
|
11
|
-
* Throws `ClawtoolAuthError` if the file is missing or empty; callers
|
|
12
|
-
* should surface an actionable message ("daemon not running? run
|
|
13
|
-
* `clawtool daemon start`"). Override `path` for tests.
|
|
14
|
-
*/
|
|
15
|
-
export class ClawtoolAuthError extends Error {
|
|
16
|
-
cause;
|
|
17
|
-
constructor(message, cause) {
|
|
18
|
-
super(message);
|
|
19
|
-
this.cause = cause;
|
|
20
|
-
this.name = 'ClawtoolAuthError';
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
export function readToken(path) {
|
|
24
|
-
const target = path ?? listenerTokenPath();
|
|
25
|
-
let raw;
|
|
26
|
-
try {
|
|
27
|
-
raw = readFileSync(target, 'utf8');
|
|
28
|
-
}
|
|
29
|
-
catch (err) {
|
|
30
|
-
throw new ClawtoolAuthError(`clawtool listener token not found at ${target} — is the daemon running?`, err);
|
|
31
|
-
}
|
|
32
|
-
const token = raw.trim();
|
|
33
|
-
if (token.length === 0) {
|
|
34
|
-
throw new ClawtoolAuthError(`clawtool listener token at ${target} is empty`);
|
|
35
|
-
}
|
|
36
|
-
return token;
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Non-throwing variant. Returns `null` if the token file is missing or
|
|
40
|
-
* empty — which is the expected case when the daemon is running in
|
|
41
|
-
* `--no-auth` mode (single-user loopback). Callers in that path should
|
|
42
|
-
* proceed with no bearer header; clawtool ignores `Authorization` when
|
|
43
|
-
* no-auth is on.
|
|
44
|
-
*/
|
|
45
|
-
export function tryReadToken(path) {
|
|
46
|
-
const target = path ?? listenerTokenPath();
|
|
47
|
-
try {
|
|
48
|
-
const raw = readFileSync(target, 'utf8');
|
|
49
|
-
const token = raw.trim();
|
|
50
|
-
return token.length > 0 ? token : null;
|
|
51
|
-
}
|
|
52
|
-
catch {
|
|
53
|
-
return null;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
//# sourceMappingURL=auth.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/integrations/clawtool/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAEtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAE9C;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAGjC;IAFV,YACC,OAAe,EACN,KAAe;QAExB,KAAK,CAAC,OAAO,CAAC,CAAA;QAFL,UAAK,GAAL,KAAK,CAAU;QAGxB,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAA;IAChC,CAAC;CACD;AAED,MAAM,UAAU,SAAS,CAAC,IAAa;IACtC,MAAM,MAAM,GAAG,IAAI,IAAI,iBAAiB,EAAE,CAAA;IAC1C,IAAI,GAAW,CAAA;IACf,IAAI,CAAC;QACJ,GAAG,GAAG,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACnC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,MAAM,IAAI,iBAAiB,CAC1B,wCAAwC,MAAM,2BAA2B,EACzE,GAAG,CACH,CAAA;IACF,CAAC;IACD,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,CAAA;IACxB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,iBAAiB,CAAC,8BAA8B,MAAM,WAAW,CAAC,CAAA;IAC7E,CAAC;IACD,OAAO,KAAK,CAAA;AACb,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,IAAa;IACzC,MAAM,MAAM,GAAG,IAAI,IAAI,iBAAiB,EAAE,CAAA;IAC1C,IAAI,CAAC;QACJ,MAAM,GAAG,GAAG,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QACxC,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,CAAA;QACxB,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAA;IACvC,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,IAAI,CAAA;IACZ,CAAC;AACF,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auth.test.d.ts","sourceRoot":"","sources":["../../../src/integrations/clawtool/auth.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { mkdtempSync, writeFileSync } from 'node:fs';
|
|
2
|
-
import { tmpdir } from 'node:os';
|
|
3
|
-
import { join } from 'node:path';
|
|
4
|
-
import { describe, expect, it } from 'vitest';
|
|
5
|
-
import { ClawtoolAuthError, readToken, tryReadToken } from './auth.js';
|
|
6
|
-
describe('readToken (strict)', () => {
|
|
7
|
-
it('returns the trimmed token from a present file', () => {
|
|
8
|
-
const dir = mkdtempSync(join(tmpdir(), 'namzu-auth-'));
|
|
9
|
-
const path = join(dir, 'token');
|
|
10
|
-
writeFileSync(path, ' abc123\n');
|
|
11
|
-
expect(readToken(path)).toBe('abc123');
|
|
12
|
-
});
|
|
13
|
-
it('throws ClawtoolAuthError when the file is missing', () => {
|
|
14
|
-
expect(() => readToken('/no/such/path/token')).toThrow(ClawtoolAuthError);
|
|
15
|
-
});
|
|
16
|
-
it('throws ClawtoolAuthError when the file is empty', () => {
|
|
17
|
-
const dir = mkdtempSync(join(tmpdir(), 'namzu-auth-'));
|
|
18
|
-
const path = join(dir, 'empty-token');
|
|
19
|
-
writeFileSync(path, ' \n \n');
|
|
20
|
-
expect(() => readToken(path)).toThrow(ClawtoolAuthError);
|
|
21
|
-
});
|
|
22
|
-
});
|
|
23
|
-
describe('tryReadToken (lenient)', () => {
|
|
24
|
-
it('returns the token when present', () => {
|
|
25
|
-
const dir = mkdtempSync(join(tmpdir(), 'namzu-auth-'));
|
|
26
|
-
const path = join(dir, 'token');
|
|
27
|
-
writeFileSync(path, 'deadbeef\n');
|
|
28
|
-
expect(tryReadToken(path)).toBe('deadbeef');
|
|
29
|
-
});
|
|
30
|
-
it('returns null for a missing file (no-auth daemon case)', () => {
|
|
31
|
-
expect(tryReadToken('/no/such/path/token')).toBeNull();
|
|
32
|
-
});
|
|
33
|
-
it('returns null for an empty file', () => {
|
|
34
|
-
const dir = mkdtempSync(join(tmpdir(), 'namzu-auth-'));
|
|
35
|
-
const path = join(dir, 'empty-token');
|
|
36
|
-
writeFileSync(path, '');
|
|
37
|
-
expect(tryReadToken(path)).toBeNull();
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
//# sourceMappingURL=auth.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auth.test.js","sourceRoot":"","sources":["../../../src/integrations/clawtool/auth.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAE7C,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAEtE,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACxD,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,aAAa,CAAC,CAAC,CAAA;QACtD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;QAC/B,aAAa,CAAC,IAAI,EAAE,YAAY,CAAC,CAAA;QACjC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IACvC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC5D,MAAM,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAA;IAC1E,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QAC1D,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,aAAa,CAAC,CAAC,CAAA;QACtD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAA;QACrC,aAAa,CAAC,IAAI,EAAE,WAAW,CAAC,CAAA;QAChC,MAAM,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAA;IACzD,CAAC,CAAC,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACvC,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACzC,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,aAAa,CAAC,CAAC,CAAA;QACtD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;QAC/B,aAAa,CAAC,IAAI,EAAE,YAAY,CAAC,CAAA;QACjC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IAC5C,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAChE,MAAM,CAAC,YAAY,CAAC,qBAAqB,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;IACvD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACzC,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,aAAa,CAAC,CAAC,CAAA;QACtD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAA;QACrC,aAAa,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;QACvB,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;IACtC,CAAC,CAAC,CAAA;AACH,CAAC,CAAC,CAAA"}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
export declare class ClawtoolBinaryError extends Error {
|
|
2
|
-
constructor(message: string);
|
|
3
|
-
}
|
|
4
|
-
export interface FindBinaryOptions {
|
|
5
|
-
/** Explicit absolute path; if set, skips PATH search and returns this. */
|
|
6
|
-
readonly override?: string;
|
|
7
|
-
/** PATH-like string for tests; defaults to `process.env.PATH`. */
|
|
8
|
-
readonly path?: string;
|
|
9
|
-
/** Binary name; default `clawtool`. Configurable for win32 `.exe` testing. */
|
|
10
|
-
readonly name?: string;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Locate the `clawtool` executable.
|
|
14
|
-
*
|
|
15
|
-
* Resolution order:
|
|
16
|
-
* 1. Explicit `override` (config: `clawtool.binary`).
|
|
17
|
-
* 2. First `<dir>/clawtool` in `$PATH` that is executable by the
|
|
18
|
-
* current user.
|
|
19
|
-
*
|
|
20
|
-
* Throws `ClawtoolBinaryError` with an actionable message when neither
|
|
21
|
-
* yields a hit. We deliberately do not auto-build from source — that would
|
|
22
|
-
* mask install errors in production deployments (see plan §M1 decision 2).
|
|
23
|
-
*/
|
|
24
|
-
export declare function findBinary(opts?: FindBinaryOptions): string;
|
|
25
|
-
//# sourceMappingURL=binary.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"binary.d.ts","sourceRoot":"","sources":["../../../src/integrations/clawtool/binary.ts"],"names":[],"mappings":"AAGA,qBAAa,mBAAoB,SAAQ,KAAK;gBACjC,OAAO,EAAE,MAAM;CAI3B;AAED,MAAM,WAAW,iBAAiB;IACjC,0EAA0E;IAC1E,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,kEAAkE;IAClE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,8EAA8E;IAC9E,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CACtB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,IAAI,GAAE,iBAAsB,GAAG,MAAM,CAe/D"}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { constants, accessSync } from 'node:fs';
|
|
2
|
-
import { delimiter, join } from 'node:path';
|
|
3
|
-
export class ClawtoolBinaryError extends Error {
|
|
4
|
-
constructor(message) {
|
|
5
|
-
super(message);
|
|
6
|
-
this.name = 'ClawtoolBinaryError';
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Locate the `clawtool` executable.
|
|
11
|
-
*
|
|
12
|
-
* Resolution order:
|
|
13
|
-
* 1. Explicit `override` (config: `clawtool.binary`).
|
|
14
|
-
* 2. First `<dir>/clawtool` in `$PATH` that is executable by the
|
|
15
|
-
* current user.
|
|
16
|
-
*
|
|
17
|
-
* Throws `ClawtoolBinaryError` with an actionable message when neither
|
|
18
|
-
* yields a hit. We deliberately do not auto-build from source — that would
|
|
19
|
-
* mask install errors in production deployments (see plan §M1 decision 2).
|
|
20
|
-
*/
|
|
21
|
-
export function findBinary(opts = {}) {
|
|
22
|
-
const name = opts.name ?? 'clawtool';
|
|
23
|
-
if (opts.override) {
|
|
24
|
-
assertExecutable(opts.override, name);
|
|
25
|
-
return opts.override;
|
|
26
|
-
}
|
|
27
|
-
const pathStr = opts.path ?? process.env.PATH ?? '';
|
|
28
|
-
const dirs = pathStr.split(delimiter).filter((d) => d.length > 0);
|
|
29
|
-
for (const dir of dirs) {
|
|
30
|
-
const candidate = join(dir, name);
|
|
31
|
-
if (isExecutable(candidate))
|
|
32
|
-
return candidate;
|
|
33
|
-
}
|
|
34
|
-
throw new ClawtoolBinaryError('clawtool binary not found in PATH. Install via `go install github.com/cogitave/clawtool/cmd/clawtool@latest` or set `clawtool.binary` in your namzu config.');
|
|
35
|
-
}
|
|
36
|
-
function assertExecutable(path, name) {
|
|
37
|
-
if (!isExecutable(path)) {
|
|
38
|
-
throw new ClawtoolBinaryError(`configured \`clawtool.binary\` path is not executable: ${path} (looking for \`${name}\`)`);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
function isExecutable(path) {
|
|
42
|
-
try {
|
|
43
|
-
accessSync(path, constants.X_OK);
|
|
44
|
-
return true;
|
|
45
|
-
}
|
|
46
|
-
catch {
|
|
47
|
-
return false;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
//# sourceMappingURL=binary.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"binary.js","sourceRoot":"","sources":["../../../src/integrations/clawtool/binary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAC/C,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAE3C,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAC7C,YAAY,OAAe;QAC1B,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAA;IAClC,CAAC;CACD;AAWD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,UAAU,CAAC,OAA0B,EAAE;IACtD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,UAAU,CAAA;IACpC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QACnB,gBAAgB,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;QACrC,OAAO,IAAI,CAAC,QAAQ,CAAA;IACrB,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAA;IACnD,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IACjE,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACxB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;QACjC,IAAI,YAAY,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAA;IAC9C,CAAC;IACD,MAAM,IAAI,mBAAmB,CAC5B,6JAA6J,CAC7J,CAAA;AACF,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAY,EAAE,IAAY;IACnD,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,mBAAmB,CAC5B,0DAA0D,IAAI,mBAAmB,IAAI,KAAK,CAC1F,CAAA;IACF,CAAC;AACF,CAAC;AAED,SAAS,YAAY,CAAC,IAAY;IACjC,IAAI,CAAC;QACJ,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,CAAA;QAChC,OAAO,IAAI,CAAA;IACZ,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,KAAK,CAAA;IACb,CAAC;AACF,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"binary.test.d.ts","sourceRoot":"","sources":["../../../src/integrations/clawtool/binary.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { chmodSync, mkdtempSync, writeFileSync } from 'node:fs';
|
|
2
|
-
import { tmpdir } from 'node:os';
|
|
3
|
-
import { delimiter, join } from 'node:path';
|
|
4
|
-
import { describe, expect, it } from 'vitest';
|
|
5
|
-
import { ClawtoolBinaryError, findBinary } from './binary.js';
|
|
6
|
-
/**
|
|
7
|
-
* POSIX file modes do not exist on Windows: `chmod` is a no-op there and
|
|
8
|
-
* `fs.stat().mode` reports a fixed value, so these cases assert a
|
|
9
|
-
* permission the platform cannot enforce. Skipping keeps the suite
|
|
10
|
-
* meaningful on Windows instead of permanently red — the behavior itself
|
|
11
|
-
* is still covered on Linux and macOS, where it actually matters.
|
|
12
|
-
*/
|
|
13
|
-
const IS_WINDOWS = process.platform === 'win32';
|
|
14
|
-
function execBin(dir, name) {
|
|
15
|
-
const path = join(dir, name);
|
|
16
|
-
writeFileSync(path, '#!/bin/sh\nexit 0\n');
|
|
17
|
-
chmodSync(path, 0o755);
|
|
18
|
-
return path;
|
|
19
|
-
}
|
|
20
|
-
describe('findBinary', () => {
|
|
21
|
-
it('returns the override when it is executable', () => {
|
|
22
|
-
const dir = mkdtempSync(join(tmpdir(), 'namzu-bin-'));
|
|
23
|
-
const path = execBin(dir, 'clawtool');
|
|
24
|
-
expect(findBinary({ override: path })).toBe(path);
|
|
25
|
-
});
|
|
26
|
-
it.skipIf(IS_WINDOWS)('throws when the override is not executable', () => {
|
|
27
|
-
const dir = mkdtempSync(join(tmpdir(), 'namzu-bin-'));
|
|
28
|
-
const path = join(dir, 'clawtool');
|
|
29
|
-
writeFileSync(path, '#!/bin/sh\nexit 0\n');
|
|
30
|
-
// no chmod +x
|
|
31
|
-
expect(() => findBinary({ override: path })).toThrow(ClawtoolBinaryError);
|
|
32
|
-
});
|
|
33
|
-
it('finds an executable in the provided PATH', () => {
|
|
34
|
-
const dir = mkdtempSync(join(tmpdir(), 'namzu-bin-'));
|
|
35
|
-
const path = execBin(dir, 'clawtool');
|
|
36
|
-
const otherDir = mkdtempSync(join(tmpdir(), 'namzu-bin-other-'));
|
|
37
|
-
const result = findBinary({ path: [otherDir, dir].join(delimiter) });
|
|
38
|
-
expect(result).toBe(path);
|
|
39
|
-
});
|
|
40
|
-
it('throws an actionable error when the binary is nowhere on PATH', () => {
|
|
41
|
-
const otherDir = mkdtempSync(join(tmpdir(), 'namzu-bin-other-'));
|
|
42
|
-
expect(() => findBinary({ path: otherDir })).toThrowError(/clawtool binary not found/);
|
|
43
|
-
});
|
|
44
|
-
it('respects a custom binary name override', () => {
|
|
45
|
-
const dir = mkdtempSync(join(tmpdir(), 'namzu-bin-'));
|
|
46
|
-
const path = execBin(dir, 'clawtool-dev');
|
|
47
|
-
expect(findBinary({ path: dir, name: 'clawtool-dev' })).toBe(path);
|
|
48
|
-
});
|
|
49
|
-
});
|
|
50
|
-
//# sourceMappingURL=binary.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"binary.test.js","sourceRoot":"","sources":["../../../src/integrations/clawtool/binary.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `ensureDaemon` — TS port of clawtool's Go `daemon.Ensure(ctx)`.
|
|
3
|
-
*
|
|
4
|
-
* Contract:
|
|
5
|
-
* 1. Read the state file. If healthy (`/v1/health` returns 200), return
|
|
6
|
-
* its endpoint + token verbatim.
|
|
7
|
-
* 2. If missing OR unhealthy, spawn `clawtool daemon start` (detached,
|
|
8
|
-
* `cmd.unref()`), wait briefly for the state file + listener, then
|
|
9
|
-
* re-probe. Return on success or throw with the underlying reason.
|
|
10
|
-
*
|
|
11
|
-
* The spawn path requires `findBinary` to return a real executable. If
|
|
12
|
-
* `autoStart` is disabled in config and the daemon isn't running, throw
|
|
13
|
-
* without spawning — surface "daemon not running" to the user instead.
|
|
14
|
-
*/
|
|
15
|
-
import type { DaemonEndpoint } from './types.js';
|
|
16
|
-
export declare class ClawtoolDaemonError extends Error {
|
|
17
|
-
readonly cause?: unknown | undefined;
|
|
18
|
-
constructor(message: string, cause?: unknown | undefined);
|
|
19
|
-
}
|
|
20
|
-
export interface EnsureDaemonOptions {
|
|
21
|
-
/** Disable auto-spawn (config: `clawtool.autoStart: false`). Default: true. */
|
|
22
|
-
readonly autoStart?: boolean;
|
|
23
|
-
/** Override binary path (config: `clawtool.binary`). */
|
|
24
|
-
readonly binary?: string;
|
|
25
|
-
/** Override endpoint base URL (config: `clawtool.endpoint`). */
|
|
26
|
-
readonly endpoint?: string;
|
|
27
|
-
/** Override token (config: `clawtool.token`). */
|
|
28
|
-
readonly token?: string;
|
|
29
|
-
/** Total deadline for the spawn → ready transition, default 10s. */
|
|
30
|
-
readonly readyTimeoutMs?: number;
|
|
31
|
-
/** Poll interval while waiting for health, default 200ms. */
|
|
32
|
-
readonly pollIntervalMs?: number;
|
|
33
|
-
/** Inject `fetch` for tests. */
|
|
34
|
-
readonly fetch?: typeof fetch;
|
|
35
|
-
}
|
|
36
|
-
export declare function ensureDaemon(opts?: EnsureDaemonOptions): Promise<DaemonEndpoint>;
|
|
37
|
-
//# sourceMappingURL=daemon.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../../src/integrations/clawtool/daemon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAOH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAEhD,qBAAa,mBAAoB,SAAQ,KAAK;IAG5C,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO;gBADxB,OAAO,EAAE,MAAM,EACN,KAAK,CAAC,EAAE,OAAO,YAAA;CAKzB;AAED,MAAM,WAAW,mBAAmB;IACnC,+EAA+E;IAC/E,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAA;IAC5B,wDAAwD;IACxD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,iDAAiD;IACjD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,oEAAoE;IACpE,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;IAChC,6DAA6D;IAC7D,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;IAChC,gCAAgC;IAChC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAA;CAC7B;AAKD,wBAAsB,YAAY,CAAC,IAAI,GAAE,mBAAwB,GAAG,OAAO,CAAC,cAAc,CAAC,CAoC1F"}
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `ensureDaemon` — TS port of clawtool's Go `daemon.Ensure(ctx)`.
|
|
3
|
-
*
|
|
4
|
-
* Contract:
|
|
5
|
-
* 1. Read the state file. If healthy (`/v1/health` returns 200), return
|
|
6
|
-
* its endpoint + token verbatim.
|
|
7
|
-
* 2. If missing OR unhealthy, spawn `clawtool daemon start` (detached,
|
|
8
|
-
* `cmd.unref()`), wait briefly for the state file + listener, then
|
|
9
|
-
* re-probe. Return on success or throw with the underlying reason.
|
|
10
|
-
*
|
|
11
|
-
* The spawn path requires `findBinary` to return a real executable. If
|
|
12
|
-
* `autoStart` is disabled in config and the daemon isn't running, throw
|
|
13
|
-
* without spawning — surface "daemon not running" to the user instead.
|
|
14
|
-
*/
|
|
15
|
-
import { spawn } from 'node:child_process';
|
|
16
|
-
import { tryReadToken } from './auth.js';
|
|
17
|
-
import { ClawtoolBinaryError, findBinary } from './binary.js';
|
|
18
|
-
import { readDaemonState } from './state.js';
|
|
19
|
-
export class ClawtoolDaemonError extends Error {
|
|
20
|
-
cause;
|
|
21
|
-
constructor(message, cause) {
|
|
22
|
-
super(message);
|
|
23
|
-
this.cause = cause;
|
|
24
|
-
this.name = 'ClawtoolDaemonError';
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
const DEFAULT_READY_TIMEOUT_MS = 10_000;
|
|
28
|
-
const DEFAULT_POLL_INTERVAL_MS = 200;
|
|
29
|
-
export async function ensureDaemon(opts = {}) {
|
|
30
|
-
const fetchFn = opts.fetch ?? globalThis.fetch;
|
|
31
|
-
const autoStart = opts.autoStart ?? true;
|
|
32
|
-
// 1. If the user supplied both endpoint and token, trust them — no
|
|
33
|
-
// discovery, no spawn. Power-user escape hatch (e.g. remote daemon
|
|
34
|
-
// or test harness). An explicit empty-string token is honored so
|
|
35
|
-
// callers can address a `--no-auth` remote daemon without needing
|
|
36
|
-
// a synthetic placeholder; only `undefined` triggers discovery.
|
|
37
|
-
if (opts.endpoint !== undefined && opts.token !== undefined) {
|
|
38
|
-
return { baseUrl: normalizeUrl(opts.endpoint), token: opts.token };
|
|
39
|
-
}
|
|
40
|
-
// 2. Try state file first.
|
|
41
|
-
const fromState = await tryStateEndpoint(opts, fetchFn);
|
|
42
|
-
if (fromState)
|
|
43
|
-
return fromState;
|
|
44
|
-
// 3. Auto-spawn if allowed.
|
|
45
|
-
if (!autoStart) {
|
|
46
|
-
throw new ClawtoolDaemonError('clawtool daemon is not running and `clawtool.autoStart` is disabled — start it manually with `clawtool daemon start`');
|
|
47
|
-
}
|
|
48
|
-
await spawnDaemon(opts);
|
|
49
|
-
// 4. Poll for readiness.
|
|
50
|
-
const deadline = Date.now() + (opts.readyTimeoutMs ?? DEFAULT_READY_TIMEOUT_MS);
|
|
51
|
-
const interval = opts.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
52
|
-
while (Date.now() < deadline) {
|
|
53
|
-
await sleep(interval);
|
|
54
|
-
const ready = await tryStateEndpoint(opts, fetchFn);
|
|
55
|
-
if (ready)
|
|
56
|
-
return ready;
|
|
57
|
-
}
|
|
58
|
-
throw new ClawtoolDaemonError(`clawtool daemon did not become ready within ${opts.readyTimeoutMs ?? DEFAULT_READY_TIMEOUT_MS}ms after spawn`);
|
|
59
|
-
}
|
|
60
|
-
async function tryStateEndpoint(opts, fetchFn) {
|
|
61
|
-
const state = readDaemonState();
|
|
62
|
-
if (!state)
|
|
63
|
-
return null;
|
|
64
|
-
const baseUrl = normalizeUrl(opts.endpoint ?? `http://127.0.0.1:${state.port}`);
|
|
65
|
-
if (!(await isHealthy(baseUrl, fetchFn)))
|
|
66
|
-
return null;
|
|
67
|
-
// Token is optional. The locally-managed daemon (`clawtool daemon start`)
|
|
68
|
-
// runs with `--no-auth` and writes no token file; bearer-mode tokens
|
|
69
|
-
// only appear when the user runs `clawtool serve` themselves. Empty
|
|
70
|
-
// token signals the MCP client to skip the Authorization header.
|
|
71
|
-
const token = opts.token ?? tryReadToken(state.token_file) ?? '';
|
|
72
|
-
return { baseUrl, token };
|
|
73
|
-
}
|
|
74
|
-
async function isHealthy(baseUrl, fetchFn) {
|
|
75
|
-
try {
|
|
76
|
-
const res = await fetchFn(`${baseUrl}/v1/health`, { method: 'GET' });
|
|
77
|
-
return res.ok;
|
|
78
|
-
}
|
|
79
|
-
catch {
|
|
80
|
-
return false;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
async function spawnDaemon(opts) {
|
|
84
|
-
let binary;
|
|
85
|
-
try {
|
|
86
|
-
binary = findBinary({ override: opts.binary });
|
|
87
|
-
}
|
|
88
|
-
catch (err) {
|
|
89
|
-
if (err instanceof ClawtoolBinaryError) {
|
|
90
|
-
throw new ClawtoolDaemonError(err.message, err);
|
|
91
|
-
}
|
|
92
|
-
throw err;
|
|
93
|
-
}
|
|
94
|
-
const child = spawn(binary, ['daemon', 'start'], {
|
|
95
|
-
stdio: 'ignore',
|
|
96
|
-
detached: true,
|
|
97
|
-
});
|
|
98
|
-
child.on('error', (err) => {
|
|
99
|
-
throw new ClawtoolDaemonError(`failed to spawn ${binary}: ${err.message}`, err);
|
|
100
|
-
});
|
|
101
|
-
child.unref();
|
|
102
|
-
}
|
|
103
|
-
function normalizeUrl(u) {
|
|
104
|
-
return u.replace(/\/$/, '');
|
|
105
|
-
}
|
|
106
|
-
function sleep(ms) {
|
|
107
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
108
|
-
}
|
|
109
|
-
//# sourceMappingURL=daemon.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../../src/integrations/clawtool/daemon.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unit tests for `ensureDaemon`. We test every path that does NOT
|
|
3
|
-
* require spawning a real subprocess (state-file read, health-poll over
|
|
4
|
-
* mocked fetch, override pass-through, autoStart=false short-circuit).
|
|
5
|
-
* The actual spawn → external `clawtool daemon start` path is exercised
|
|
6
|
-
* by live end-to-end smoke against a real clawtool daemon; automating
|
|
7
|
-
* it cleanly requires a CI fixture that will land when we wire
|
|
8
|
-
* integration tests.
|
|
9
|
-
*/
|
|
10
|
-
export {};
|
|
11
|
-
//# sourceMappingURL=daemon.test.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"daemon.test.d.ts","sourceRoot":"","sources":["../../../src/integrations/clawtool/daemon.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unit tests for `ensureDaemon`. We test every path that does NOT
|
|
3
|
-
* require spawning a real subprocess (state-file read, health-poll over
|
|
4
|
-
* mocked fetch, override pass-through, autoStart=false short-circuit).
|
|
5
|
-
* The actual spawn → external `clawtool daemon start` path is exercised
|
|
6
|
-
* by live end-to-end smoke against a real clawtool daemon; automating
|
|
7
|
-
* it cleanly requires a CI fixture that will land when we wire
|
|
8
|
-
* integration tests.
|
|
9
|
-
*/
|
|
10
|
-
import { mkdtempSync, writeFileSync } from 'node:fs';
|
|
11
|
-
import { tmpdir } from 'node:os';
|
|
12
|
-
import { join } from 'node:path';
|
|
13
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
14
|
-
import { ClawtoolDaemonError, ensureDaemon } from './daemon.js';
|
|
15
|
-
function stateFileFixture() {
|
|
16
|
-
const home = mkdtempSync(join(tmpdir(), 'namzu-daemon-'));
|
|
17
|
-
const configDir = join(home, '.config', 'clawtool');
|
|
18
|
-
const tokenPath = join(configDir, 'listener-token');
|
|
19
|
-
// Mirror what `clawtool daemon start` writes: state JSON + (sometimes) token.
|
|
20
|
-
const state = {
|
|
21
|
-
version: 1,
|
|
22
|
-
pid: 99999,
|
|
23
|
-
port: 51234,
|
|
24
|
-
started_at: '2026-05-24T12:00:00Z',
|
|
25
|
-
token_file: tokenPath,
|
|
26
|
-
log_file: join(home, '.local', 'state', 'clawtool', 'daemon.log'),
|
|
27
|
-
};
|
|
28
|
-
const fs = require('node:fs');
|
|
29
|
-
fs.mkdirSync(configDir, { recursive: true });
|
|
30
|
-
fs.writeFileSync(join(configDir, 'daemon.json'), JSON.stringify(state));
|
|
31
|
-
return { dir: home, tokenPath };
|
|
32
|
-
}
|
|
33
|
-
describe('ensureDaemon', () => {
|
|
34
|
-
let originalEnv;
|
|
35
|
-
beforeEach(() => {
|
|
36
|
-
originalEnv = process.env;
|
|
37
|
-
process.env = { ...originalEnv };
|
|
38
|
-
});
|
|
39
|
-
afterEach(() => {
|
|
40
|
-
process.env = originalEnv;
|
|
41
|
-
});
|
|
42
|
-
it('returns immediately when endpoint AND token are both overridden — no daemon, no probe', async () => {
|
|
43
|
-
const fetchMock = vi.fn();
|
|
44
|
-
const result = await ensureDaemon({
|
|
45
|
-
endpoint: 'http://daemon.example.com:9999',
|
|
46
|
-
token: 'preset-token',
|
|
47
|
-
fetch: fetchMock,
|
|
48
|
-
});
|
|
49
|
-
expect(result).toEqual({ baseUrl: 'http://daemon.example.com:9999', token: 'preset-token' });
|
|
50
|
-
expect(fetchMock).not.toHaveBeenCalled();
|
|
51
|
-
});
|
|
52
|
-
it('uses state-file endpoint when daemon is healthy and no token file present (no-auth mode)', async () => {
|
|
53
|
-
const { dir } = stateFileFixture();
|
|
54
|
-
process.env = { ...originalEnv, XDG_CONFIG_HOME: join(dir, '.config') };
|
|
55
|
-
const fetchMock = vi
|
|
56
|
-
.fn()
|
|
57
|
-
.mockResolvedValue(new Response('{"status":"ok"}', { status: 200 }));
|
|
58
|
-
const result = await ensureDaemon({ fetch: fetchMock });
|
|
59
|
-
expect(result.baseUrl).toBe('http://127.0.0.1:51234');
|
|
60
|
-
expect(result.token).toBe(''); // no token file = no-auth daemon
|
|
61
|
-
expect(fetchMock).toHaveBeenCalledWith('http://127.0.0.1:51234/v1/health', { method: 'GET' });
|
|
62
|
-
});
|
|
63
|
-
it('uses state-file endpoint with token from file when present', async () => {
|
|
64
|
-
const { dir, tokenPath } = stateFileFixture();
|
|
65
|
-
writeFileSync(tokenPath, 'deadbeef\n');
|
|
66
|
-
process.env = { ...originalEnv, XDG_CONFIG_HOME: join(dir, '.config') };
|
|
67
|
-
const fetchMock = vi
|
|
68
|
-
.fn()
|
|
69
|
-
.mockResolvedValue(new Response('{"status":"ok"}', { status: 200 }));
|
|
70
|
-
const result = await ensureDaemon({ fetch: fetchMock });
|
|
71
|
-
expect(result.token).toBe('deadbeef');
|
|
72
|
-
});
|
|
73
|
-
it('config.token wins over the file token', async () => {
|
|
74
|
-
const { dir, tokenPath } = stateFileFixture();
|
|
75
|
-
writeFileSync(tokenPath, 'file-token\n');
|
|
76
|
-
process.env = { ...originalEnv, XDG_CONFIG_HOME: join(dir, '.config') };
|
|
77
|
-
const fetchMock = vi
|
|
78
|
-
.fn()
|
|
79
|
-
.mockResolvedValue(new Response('{"status":"ok"}', { status: 200 }));
|
|
80
|
-
const result = await ensureDaemon({ fetch: fetchMock, token: 'override-token' });
|
|
81
|
-
expect(result.token).toBe('override-token');
|
|
82
|
-
});
|
|
83
|
-
it('config.endpoint overrides the state-file port', async () => {
|
|
84
|
-
const { dir } = stateFileFixture();
|
|
85
|
-
process.env = { ...originalEnv, XDG_CONFIG_HOME: join(dir, '.config') };
|
|
86
|
-
const fetchMock = vi
|
|
87
|
-
.fn()
|
|
88
|
-
.mockResolvedValue(new Response('{"status":"ok"}', { status: 200 }));
|
|
89
|
-
const result = await ensureDaemon({
|
|
90
|
-
fetch: fetchMock,
|
|
91
|
-
endpoint: 'http://my-remote-daemon:8765',
|
|
92
|
-
});
|
|
93
|
-
expect(result.baseUrl).toBe('http://my-remote-daemon:8765');
|
|
94
|
-
expect(fetchMock).toHaveBeenCalledWith('http://my-remote-daemon:8765/v1/health', {
|
|
95
|
-
method: 'GET',
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
it('throws ClawtoolDaemonError when autoStart=false and the daemon is unreachable', async () => {
|
|
99
|
-
// Point to an XDG dir with no state file → readDaemonState returns null
|
|
100
|
-
// → tryStateEndpoint returns null → autoStart short-circuits.
|
|
101
|
-
const empty = mkdtempSync(join(tmpdir(), 'namzu-daemon-empty-'));
|
|
102
|
-
process.env = { ...originalEnv, XDG_CONFIG_HOME: empty };
|
|
103
|
-
await expect(ensureDaemon({ autoStart: false, fetch: vi.fn() })).rejects.toThrow(ClawtoolDaemonError);
|
|
104
|
-
});
|
|
105
|
-
it('treats non-200 /v1/health as unhealthy and (with autoStart=false) gives up', async () => {
|
|
106
|
-
const { dir } = stateFileFixture();
|
|
107
|
-
process.env = { ...originalEnv, XDG_CONFIG_HOME: join(dir, '.config') };
|
|
108
|
-
const fetchMock = vi.fn().mockResolvedValue(new Response('', { status: 503 }));
|
|
109
|
-
await expect(ensureDaemon({ autoStart: false, fetch: fetchMock })).rejects.toThrow(ClawtoolDaemonError);
|
|
110
|
-
});
|
|
111
|
-
it('treats fetch error as unhealthy and (with autoStart=false) gives up', async () => {
|
|
112
|
-
const { dir } = stateFileFixture();
|
|
113
|
-
process.env = { ...originalEnv, XDG_CONFIG_HOME: join(dir, '.config') };
|
|
114
|
-
const fetchMock = vi.fn().mockRejectedValue(new Error('ECONNREFUSED'));
|
|
115
|
-
await expect(ensureDaemon({ autoStart: false, fetch: fetchMock })).rejects.toThrow(ClawtoolDaemonError);
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
//# sourceMappingURL=daemon.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"daemon.test.js","sourceRoot":"","sources":["../../../src/integrations/clawtool/daemon.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Client for clawtool's `POST /v1/send_message` — the canonical agent
|
|
3
|
-
* dispatcher. Returns an async iterable of normalized text frames so the
|
|
4
|
-
* TUI can stream tokens into the transcript without caring about the
|
|
5
|
-
* upstream CLI's exact wire format.
|
|
6
|
-
*
|
|
7
|
-
* The clawtool server passes through the upstream agent's NDJSON frames
|
|
8
|
-
* verbatim, and each upstream family emits a different shape. We do
|
|
9
|
-
* **best-effort normalization**: extract any `text` /
|
|
10
|
-
* `content` string fields as visible deltas; collapse `error` lines into
|
|
11
|
-
* error events; everything else (tool_use, tool_result, ping, message
|
|
12
|
-
* envelopes) is silently consumed for now — tool-call surfacing lands
|
|
13
|
-
* with the tool permission overlay.
|
|
14
|
-
*/
|
|
15
|
-
import { type EnsureDaemonOptions } from './daemon.js';
|
|
16
|
-
export type DispatchEvent = {
|
|
17
|
-
readonly kind: 'delta';
|
|
18
|
-
readonly text: string;
|
|
19
|
-
} | {
|
|
20
|
-
readonly kind: 'done';
|
|
21
|
-
} | {
|
|
22
|
-
readonly kind: 'error';
|
|
23
|
-
readonly message: string;
|
|
24
|
-
};
|
|
25
|
-
export interface SendMessageOptions extends EnsureDaemonOptions {
|
|
26
|
-
readonly instance: string;
|
|
27
|
-
readonly prompt: string;
|
|
28
|
-
/** Pass-through dispatch options (e.g. session_id, model, format). */
|
|
29
|
-
readonly opts?: Record<string, unknown>;
|
|
30
|
-
readonly signal?: AbortSignal;
|
|
31
|
-
}
|
|
32
|
-
export declare function sendMessage(opts: SendMessageOptions): AsyncIterable<DispatchEvent>;
|
|
33
|
-
//# sourceMappingURL=dispatch.d.ts.map
|