zelari-code 0.4.3 → 0.7.5
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 +42 -0
- package/bin/zelari-code.js +1 -1
- package/dist/agents/councilApi.js +7 -7
- package/dist/agents/councilApi.js.map +1 -1
- package/dist/agents/councilDirectives.js +3 -3
- package/dist/agents/promoteMember.js +2 -2
- package/dist/agents/roles.js +50 -32
- package/dist/agents/roles.js.map +1 -1
- package/dist/agents/skills/builtin/debugging.js +4 -4
- package/dist/agents/skills/builtin/debugging.js.map +1 -1
- package/dist/agents/skills/builtin/docs.js +23 -13
- package/dist/agents/skills/builtin/docs.js.map +1 -1
- package/dist/agents/skills/builtin/git-ops.js +3 -3
- package/dist/agents/skills/builtin/git-ops.js.map +1 -1
- package/dist/agents/skills/builtin/planning.js +4 -4
- package/dist/agents/skills/builtin/planning.js.map +1 -1
- package/dist/agents/skills/builtin/refactoring.js +3 -3
- package/dist/agents/skills/builtin/refactoring.js.map +1 -1
- package/dist/agents/skills/builtin/review.js +9 -9
- package/dist/agents/skills/builtin/review.js.map +1 -1
- package/dist/agents/skills/builtin/testing.js +3 -3
- package/dist/agents/skills/builtin/testing.js.map +1 -1
- package/dist/agents/tools.js +2 -9
- package/dist/agents/tools.js.map +1 -1
- package/dist/cli/app.js +72 -33
- package/dist/cli/app.js.map +1 -1
- package/dist/cli/compaction.js.map +1 -1
- package/dist/cli/components/ChatStream.js +43 -82
- package/dist/cli/components/ChatStream.js.map +1 -1
- package/dist/cli/components/CollapsibleToolOutput.js +8 -21
- package/dist/cli/components/CollapsibleToolOutput.js.map +1 -1
- package/dist/cli/components/Header.js +6 -18
- package/dist/cli/components/Header.js.map +1 -1
- package/dist/cli/components/LiveRegion.js +54 -0
- package/dist/cli/components/LiveRegion.js.map +1 -0
- package/dist/cli/components/Sidebar.js +33 -31
- package/dist/cli/components/Sidebar.js.map +1 -1
- package/dist/cli/components/StatusBar.js +42 -0
- package/dist/cli/components/StatusBar.js.map +1 -0
- package/dist/cli/components/ToolOutput.js +68 -0
- package/dist/cli/components/ToolOutput.js.map +1 -0
- package/dist/cli/components/toolFormat.js +195 -0
- package/dist/cli/components/toolFormat.js.map +1 -0
- package/dist/cli/councilDispatcher.js +1 -1
- package/dist/cli/councilDispatcher.js.map +1 -1
- package/dist/cli/grokOAuth.js +93 -75
- package/dist/cli/grokOAuth.js.map +1 -1
- package/dist/cli/headless.js +137 -0
- package/dist/cli/headless.js.map +1 -0
- package/dist/cli/hooks/chatState.js +139 -0
- package/dist/cli/hooks/chatState.js.map +1 -0
- package/dist/cli/hooks/eventsToMessages.js +42 -11
- package/dist/cli/hooks/eventsToMessages.js.map +1 -1
- package/dist/cli/hooks/messageHelpers.js +72 -15
- package/dist/cli/hooks/messageHelpers.js.map +1 -1
- package/dist/cli/hooks/useBatchedMessages.js +71 -0
- package/dist/cli/hooks/useBatchedMessages.js.map +1 -0
- package/dist/cli/hooks/useChatTurn.js +453 -84
- package/dist/cli/hooks/useChatTurn.js.map +1 -1
- package/dist/cli/hooks/useSession.js +24 -3
- package/dist/cli/hooks/useSession.js.map +1 -1
- package/dist/cli/hooks/useSlashDispatch.js +13 -2
- package/dist/cli/hooks/useSlashDispatch.js.map +1 -1
- package/dist/cli/main.bundled.js +10607 -7889
- package/dist/cli/main.bundled.js.map +4 -4
- package/dist/cli/main.js +120 -2
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/mcp/mcpClient.js +152 -0
- package/dist/cli/mcp/mcpClient.js.map +1 -0
- package/dist/cli/mcp/mcpManager.js +139 -0
- package/dist/cli/mcp/mcpManager.js.map +1 -0
- package/dist/cli/provider/openai-compatible.js +9 -2
- package/dist/cli/provider/openai-compatible.js.map +1 -1
- package/dist/cli/refreshRegistry.js +9 -6
- package/dist/cli/refreshRegistry.js.map +1 -1
- package/dist/cli/runHeadless.js +160 -0
- package/dist/cli/runHeadless.js.map +1 -0
- package/dist/cli/sessionManager.js +1 -1
- package/dist/cli/sessionManager.js.map +1 -1
- package/dist/cli/skillSuggest.js +1 -1
- package/dist/cli/skillsMd.js +155 -0
- package/dist/cli/skillsMd.js.map +1 -0
- package/dist/cli/slashHandlers/branch.js +11 -2
- package/dist/cli/slashHandlers/branch.js.map +1 -1
- package/dist/cli/slashHandlers/git.js +0 -75
- package/dist/cli/slashHandlers/git.js.map +1 -1
- package/dist/cli/slashHandlers/promoteMember.js +25 -0
- package/dist/cli/slashHandlers/promoteMember.js.map +1 -0
- package/dist/cli/slashHandlers/skills.js +16 -0
- package/dist/cli/slashHandlers/skills.js.map +1 -1
- package/dist/cli/slashHandlers/transcript.js +13 -0
- package/dist/cli/slashHandlers/transcript.js.map +1 -0
- package/dist/cli/slashHandlers/updater.js +40 -0
- package/dist/cli/slashHandlers/updater.js.map +1 -0
- package/dist/cli/toolRegistry.js +37 -6
- package/dist/cli/toolRegistry.js.map +1 -1
- package/dist/cli/wizard/firstRun.js +63 -0
- package/dist/cli/wizard/firstRun.js.map +1 -0
- package/dist/cli/wizard/index.js +150 -0
- package/dist/cli/wizard/index.js.map +1 -0
- package/dist/cli/wizard/runWizard.js +137 -0
- package/dist/cli/wizard/runWizard.js.map +1 -0
- package/dist/cli/wizard/useWizardState.js +151 -0
- package/dist/cli/wizard/useWizardState.js.map +1 -0
- package/dist/cli/workspace/paths.js +20 -13
- package/dist/cli/workspace/paths.js.map +1 -1
- package/dist/cli/workspace/storage.js +7 -3
- package/dist/cli/workspace/storage.js.map +1 -1
- package/dist/cli/workspace/stubs.js +122 -44
- package/dist/cli/workspace/stubs.js.map +1 -1
- package/dist/cli/workspace/toolRegistry.js +2 -2
- package/dist/cli/workspace/toolRegistry.js.map +1 -1
- package/dist/cli/workspace/workspaceSummary.js +255 -0
- package/dist/cli/workspace/workspaceSummary.js.map +1 -0
- package/dist/main/core/AgentHarness.js +36 -7
- package/dist/main/core/AgentHarness.js.map +1 -1
- package/dist/main/core/tools/builtin/listFiles.js +43 -5
- package/dist/main/core/tools/builtin/listFiles.js.map +1 -1
- package/dist/main/core/tools/builtin/search.js +28 -120
- package/dist/main/core/tools/builtin/search.js.map +1 -1
- package/package.json +6 -1
- package/dist/cli/oauthCallbackServer.js +0 -207
- package/dist/cli/oauthCallbackServer.js.map +0 -1
- package/dist/main/core/tools/builtin/_walk.js +0 -129
- package/dist/main/core/tools/builtin/_walk.js.map +0 -1
- package/dist/main/core/tools/builtin/diff.js +0 -477
- package/dist/main/core/tools/builtin/diff.js.map +0 -1
|
@@ -2,143 +2,51 @@ import { z } from 'zod';
|
|
|
2
2
|
import { promises as fs } from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { typedOk, typedErr } from '../toolTypes.js';
|
|
5
|
-
import { walk, filterByInclude, DEFAULT_EXCLUDES, } from './_walk.js';
|
|
6
|
-
/**
|
|
7
|
-
* grep_content — Regex search across one file OR a directory tree.
|
|
8
|
-
*
|
|
9
|
-
* Two modes:
|
|
10
|
-
* 1. Single-file: `path` is a regular file → search it.
|
|
11
|
-
* 2. Recursive: `path` is a directory → walk it (respecting `include` /
|
|
12
|
-
* `exclude` globs and `maxDepth`) and search each matched file.
|
|
13
|
-
*
|
|
14
|
-
* Backward-compatible: existing callers passing a single-file `path`
|
|
15
|
-
* keep the v0.3.x behavior unchanged.
|
|
16
|
-
*
|
|
17
|
-
* Glob syntax: `*`, `?`, `[abc]`, `**` (recursive). See _walk.ts.
|
|
18
|
-
*/
|
|
19
5
|
const GrepContentArgsSchema = z.object({
|
|
20
|
-
/** File OR directory to search (relative to cwd or absolute). */
|
|
21
6
|
path: z.string().min(1),
|
|
22
|
-
/** Regex pattern (no flags — gm is hardcoded). */
|
|
23
7
|
pattern: z.string().min(1),
|
|
24
|
-
/** Context lines before/after each match. */
|
|
25
8
|
contextLines: z.number().int().nonnegative().default(2),
|
|
26
|
-
/** Max matches returned (total matches still counted). */
|
|
27
9
|
maxMatches: z.number().int().positive().max(1000).default(50),
|
|
28
|
-
/**
|
|
29
|
-
* Glob patterns to INCLUDE when path is a directory (e.g. ['*.ts', '*.tsx']).
|
|
30
|
-
* Default ['*'] = all files. Ignored when path is a file.
|
|
31
|
-
*/
|
|
32
|
-
include: z.array(z.string()).default(['*']),
|
|
33
|
-
/**
|
|
34
|
-
* Glob patterns to EXCLUDE when path is a directory (e.g. ['*.test.ts']).
|
|
35
|
-
* Defaults to common noise dirs. Ignored when path is a file.
|
|
36
|
-
*/
|
|
37
|
-
exclude: z.array(z.string()).default(DEFAULT_EXCLUDES),
|
|
38
|
-
/** Max recursion depth when path is a directory (default 8). */
|
|
39
|
-
maxDepth: z.number().int().positive().max(15).default(8),
|
|
40
10
|
});
|
|
41
|
-
export { GrepContentArgsSchema };
|
|
42
|
-
async function searchFile(absPath, relPath, regex, contextLines, remainingSlots) {
|
|
43
|
-
let buf;
|
|
44
|
-
try {
|
|
45
|
-
buf = await fs.readFile(absPath, 'utf-8');
|
|
46
|
-
}
|
|
47
|
-
catch {
|
|
48
|
-
return { matches: [], total: 0, truncated: false }; // unreadable file → skip
|
|
49
|
-
}
|
|
50
|
-
const lines = buf.split('\n');
|
|
51
|
-
const matches = [];
|
|
52
|
-
let total = 0;
|
|
53
|
-
let truncated = false;
|
|
54
|
-
for (let i = 0; i < lines.length; i++) {
|
|
55
|
-
regex.lastIndex = 0;
|
|
56
|
-
if (regex.test(lines[i])) {
|
|
57
|
-
total++;
|
|
58
|
-
if (matches.length < remainingSlots) {
|
|
59
|
-
const startBefore = Math.max(0, i - contextLines);
|
|
60
|
-
const endAfter = Math.min(lines.length - 1, i + contextLines);
|
|
61
|
-
matches.push({
|
|
62
|
-
file: absPath,
|
|
63
|
-
relPath,
|
|
64
|
-
line: i + 1,
|
|
65
|
-
text: lines[i],
|
|
66
|
-
context: {
|
|
67
|
-
before: lines.slice(startBefore, i),
|
|
68
|
-
after: lines.slice(i + 1, endAfter + 1),
|
|
69
|
-
},
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
truncated = true;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
return { matches, total, truncated };
|
|
78
|
-
}
|
|
79
|
-
async function isDirectory(p) {
|
|
80
|
-
try {
|
|
81
|
-
const stat = await fs.stat(p);
|
|
82
|
-
return stat.isDirectory();
|
|
83
|
-
}
|
|
84
|
-
catch {
|
|
85
|
-
return false;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
11
|
export const grepContentTool = {
|
|
89
12
|
name: 'grep_content',
|
|
90
|
-
description: 'Regex search for content in a file
|
|
91
|
-
'When path is a directory, include/exclude globs filter which files are searched ' +
|
|
92
|
-
'(default: all files, excluding node_modules/dist/.git/etc.). Returns matches with ' +
|
|
93
|
-
'line numbers and surrounding context. Single-file mode preserves v0.3.x behavior.',
|
|
13
|
+
description: 'Regex search for content in a file. Returns matches with line numbers and context.',
|
|
94
14
|
permissions: ['read'],
|
|
95
|
-
timeoutMs:
|
|
15
|
+
timeoutMs: 10000,
|
|
96
16
|
inputSchema: GrepContentArgsSchema,
|
|
97
17
|
execute: async (args, ctx) => {
|
|
98
18
|
try {
|
|
99
|
-
const
|
|
19
|
+
const absPath = path.isAbsolute(args.path) ? args.path : path.join(ctx.cwd, args.path);
|
|
20
|
+
const content = await fs.readFile(absPath, { encoding: 'utf-8', signal: ctx.signal });
|
|
21
|
+
const text = typeof content === 'string' ? content : content.toString('utf-8');
|
|
22
|
+
const lines = text.split('\n');
|
|
100
23
|
const regex = new RegExp(args.pattern, 'gm');
|
|
101
|
-
|
|
102
|
-
if (!(await isDirectory(absRoot))) {
|
|
103
|
-
const single = await searchFile(absRoot, args.path, regex, args.contextLines, args.maxMatches);
|
|
104
|
-
return typedOk({
|
|
105
|
-
matches: single.matches,
|
|
106
|
-
totalMatches: single.total,
|
|
107
|
-
truncated: single.truncated,
|
|
108
|
-
filesSearched: 1,
|
|
109
|
-
filesInTree: 1,
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
// ── Recursive (directory) mode ──────────────────────────────
|
|
113
|
-
const allEntries = [];
|
|
114
|
-
await walk(absRoot, '', 0, args.maxDepth, args.exclude, allEntries, ctx.signal);
|
|
115
|
-
const matchedFiles = filterByInclude(allEntries, args.include);
|
|
116
|
-
const allMatches = [];
|
|
24
|
+
const matches = [];
|
|
117
25
|
let totalMatches = 0;
|
|
118
26
|
let truncated = false;
|
|
119
|
-
let
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
27
|
+
for (let i = 0; i < lines.length; i++) {
|
|
28
|
+
if (regex.test(lines[i])) {
|
|
29
|
+
regex.lastIndex = 0; // Reset global regex state
|
|
30
|
+
totalMatches++;
|
|
31
|
+
if (matches.length < args.maxMatches) {
|
|
32
|
+
const startBefore = Math.max(0, i - args.contextLines);
|
|
33
|
+
const endAfter = Math.min(lines.length - 1, i + args.contextLines);
|
|
34
|
+
matches.push({
|
|
35
|
+
file: absPath,
|
|
36
|
+
line: i + 1,
|
|
37
|
+
text: lines[i],
|
|
38
|
+
context: {
|
|
39
|
+
before: lines.slice(startBefore, i),
|
|
40
|
+
after: lines.slice(i + 1, endAfter + 1),
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
truncated = true;
|
|
46
|
+
}
|
|
126
47
|
}
|
|
127
|
-
const absFile = path.join(absRoot, entry.name);
|
|
128
|
-
const result = await searchFile(absFile, entry.name, regex, args.contextLines, args.maxMatches - allMatches.length);
|
|
129
|
-
filesSearched++;
|
|
130
|
-
totalMatches += result.total;
|
|
131
|
-
if (result.truncated)
|
|
132
|
-
truncated = true;
|
|
133
|
-
allMatches.push(...result.matches);
|
|
134
48
|
}
|
|
135
|
-
return typedOk({
|
|
136
|
-
matches: allMatches,
|
|
137
|
-
totalMatches,
|
|
138
|
-
truncated,
|
|
139
|
-
filesSearched,
|
|
140
|
-
filesInTree: matchedFiles.length,
|
|
141
|
-
});
|
|
49
|
+
return typedOk({ matches, totalMatches, truncated });
|
|
142
50
|
}
|
|
143
51
|
catch (err) {
|
|
144
52
|
return typedErr(err instanceof Error ? err.message : String(err));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../../../../src/main/core/tools/builtin/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAuB,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../../../../src/main/core/tools/builtin/search.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zelari-code",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.5",
|
|
4
4
|
"description": "Zelari Code — AI Council coding agent CLI. Multi-agent orchestration (Caronte, Nettuno, Gerione, Plutone, Minosse, Lucifero) with slash commands, provider-agnostic LLM streaming, and self-update.",
|
|
5
5
|
"author": "N-THEM Studio",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
7
7
|
"type": "module",
|
|
8
|
+
"workspaces": [
|
|
9
|
+
"packages/*"
|
|
10
|
+
],
|
|
8
11
|
"main": "dist/cli/main.js",
|
|
9
12
|
"bin": {
|
|
10
13
|
"zelari-code": "./bin/zelari-code.js"
|
|
@@ -24,12 +27,14 @@
|
|
|
24
27
|
"build": "tsc -p tsconfig.json && node scripts/bundle-cli.mjs",
|
|
25
28
|
"build:cli": "tsc -p tsconfig.json && node scripts/bundle-cli.mjs",
|
|
26
29
|
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
30
|
+
"pretest": "npm run build --workspace=@zelari/core",
|
|
27
31
|
"test": "vitest run",
|
|
28
32
|
"test:watch": "vitest",
|
|
29
33
|
"smoke": "node bin/zelari-code.js --version",
|
|
30
34
|
"prepublishOnly": "node scripts/prepublish.mjs"
|
|
31
35
|
},
|
|
32
36
|
"dependencies": {
|
|
37
|
+
"@zelari/core": "0.7.5",
|
|
33
38
|
"ink": "^6.8.0",
|
|
34
39
|
"ink-text-input": "^6.0.0",
|
|
35
40
|
"react": "^19.2.7",
|
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* oauthCallbackServer — minimal HTTP server for OAuth browser-flow callbacks.
|
|
3
|
-
*
|
|
4
|
-
* The CLI uses this to receive the redirect from the OAuth provider after
|
|
5
|
-
* the user authenticates in their browser. The server:
|
|
6
|
-
* - listens on a local port (default 14523) on 127.0.0.1
|
|
7
|
-
* - captures `?code=XXX` from the first request to `expectedPath`
|
|
8
|
-
* - returns a friendly 200 HTML response so the user can close the tab
|
|
9
|
-
* - resolves a single `waitForCode()` Promise with the code, or rejects on timeout
|
|
10
|
-
* - shuts itself down after capture (or via explicit close())
|
|
11
|
-
*
|
|
12
|
-
* No deps — pure node:http. Browser-importable for jsdom tests.
|
|
13
|
-
*
|
|
14
|
-
* @see docs/plans/2026-06-29-anathema-coder-v2.md (Task 16.1)
|
|
15
|
-
*/
|
|
16
|
-
import { createServer } from 'node:http';
|
|
17
|
-
const DEFAULT_SUCCESS_HTML = `
|
|
18
|
-
<!DOCTYPE html>
|
|
19
|
-
<html lang="en">
|
|
20
|
-
<head>
|
|
21
|
-
<meta charset="UTF-8">
|
|
22
|
-
<title>zelari-code OAuth</title>
|
|
23
|
-
</head>
|
|
24
|
-
<body style="font-family: -apple-system, BlinkMacSystemFont, sans-serif; padding: 40px; text-align: center; color: #1a1a1a;">
|
|
25
|
-
<h1 style="color: #00aa33;">✓ Authentication complete</h1>
|
|
26
|
-
<p>You can close this tab and return to zelari-code.</p>
|
|
27
|
-
</body>
|
|
28
|
-
</html>
|
|
29
|
-
`.trim();
|
|
30
|
-
export class OAuthCallbackTimeoutError extends Error {
|
|
31
|
-
constructor(timeoutMs) {
|
|
32
|
-
super(`OAuth callback not received within ${timeoutMs}ms`);
|
|
33
|
-
this.name = 'OAuthCallbackTimeoutError';
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
export class OAuthCallbackClosedError extends Error {
|
|
37
|
-
constructor() {
|
|
38
|
-
super('OAuth callback server closed before receiving a callback');
|
|
39
|
-
this.name = 'OAuthCallbackClosedError';
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
export class OAuthCallbackError extends Error {
|
|
43
|
-
constructor(message) {
|
|
44
|
-
super(message);
|
|
45
|
-
this.name = 'OAuthCallbackError';
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Start the OAuth callback server. Returns a handle with port + waitForCode + close.
|
|
50
|
-
*
|
|
51
|
-
* The first request to `expectedPath` resolves waitForCode with the `code`
|
|
52
|
-
* query parameter. Any other path returns a 404.
|
|
53
|
-
*/
|
|
54
|
-
export function startOAuthCallbackServer(options = {}) {
|
|
55
|
-
const host = options.host ?? '127.0.0.1';
|
|
56
|
-
const preferredPort = options.port ?? 14523;
|
|
57
|
-
const timeoutMs = options.timeoutMs ?? 60_000;
|
|
58
|
-
const expectedPath = options.expectedPath ?? '/oauth/callback';
|
|
59
|
-
const successHtml = options.successHtml ?? DEFAULT_SUCCESS_HTML;
|
|
60
|
-
return new Promise((resolveStart, rejectStart) => {
|
|
61
|
-
let resolved = false;
|
|
62
|
-
let resolveCode = null;
|
|
63
|
-
let rejectCode = null;
|
|
64
|
-
let timeoutHandle = null;
|
|
65
|
-
const server = createServer((req, res) => {
|
|
66
|
-
try {
|
|
67
|
-
if (!req.url) {
|
|
68
|
-
res.writeHead(400, { 'Content-Type': 'text/plain' });
|
|
69
|
-
res.end('Bad request');
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
// Parse path + query.
|
|
73
|
-
const url = new URL(req.url, `http://${host}:${preferredPort}`);
|
|
74
|
-
if (url.pathname !== expectedPath) {
|
|
75
|
-
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
|
76
|
-
res.end('Not found');
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
const code = url.searchParams.get('code');
|
|
80
|
-
const state = url.searchParams.get('state');
|
|
81
|
-
const errorParam = url.searchParams.get('error');
|
|
82
|
-
const errorDescription = url.searchParams.get('error_description');
|
|
83
|
-
// Capture any extra params for diagnostics / future use.
|
|
84
|
-
const extras = {};
|
|
85
|
-
for (const [key, value] of url.searchParams.entries()) {
|
|
86
|
-
if (key !== 'code' && key !== 'state' && key !== 'error' && key !== 'error_description') {
|
|
87
|
-
extras[key] = value;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
const params = {
|
|
91
|
-
...(code ? { code } : {}),
|
|
92
|
-
...(state ? { state } : {}),
|
|
93
|
-
...(errorParam ? { error: errorParam } : {}),
|
|
94
|
-
...(errorDescription ? { errorDescription } : {}),
|
|
95
|
-
extras,
|
|
96
|
-
};
|
|
97
|
-
if (errorParam) {
|
|
98
|
-
// OAuth provider returned an error (e.g. user denied).
|
|
99
|
-
res.writeHead(400, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
100
|
-
res.end(`<h1>OAuth error: ${errorParam}</h1>`);
|
|
101
|
-
if (rejectCode && !resolved) {
|
|
102
|
-
resolved = true;
|
|
103
|
-
if (timeoutHandle)
|
|
104
|
-
clearTimeout(timeoutHandle);
|
|
105
|
-
rejectCode(new OAuthCallbackError(`OAuth provider returned error: ${errorParam}`));
|
|
106
|
-
}
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
if (!code) {
|
|
110
|
-
res.writeHead(400, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
111
|
-
res.end('<h1>Missing <code>code</code> query parameter</h1>');
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
// Success.
|
|
115
|
-
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
116
|
-
res.end(successHtml);
|
|
117
|
-
if (resolveCode && !resolved) {
|
|
118
|
-
resolved = true;
|
|
119
|
-
if (timeoutHandle)
|
|
120
|
-
clearTimeout(timeoutHandle);
|
|
121
|
-
resolveCode(params);
|
|
122
|
-
}
|
|
123
|
-
// Give the response a moment to flush before closing.
|
|
124
|
-
setTimeout(() => {
|
|
125
|
-
try {
|
|
126
|
-
server.close();
|
|
127
|
-
}
|
|
128
|
-
catch {
|
|
129
|
-
// already closed
|
|
130
|
-
}
|
|
131
|
-
}, 100);
|
|
132
|
-
}
|
|
133
|
-
catch (err) {
|
|
134
|
-
// Defensive: never crash the server on a single bad request.
|
|
135
|
-
try {
|
|
136
|
-
res.writeHead(500, { 'Content-Type': 'text/plain' });
|
|
137
|
-
res.end('Internal error');
|
|
138
|
-
}
|
|
139
|
-
catch {
|
|
140
|
-
// ignore
|
|
141
|
-
}
|
|
142
|
-
if (!resolved && rejectCode) {
|
|
143
|
-
resolved = true;
|
|
144
|
-
if (timeoutHandle)
|
|
145
|
-
clearTimeout(timeoutHandle);
|
|
146
|
-
rejectCode(err instanceof Error ? err : new Error(String(err)));
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
});
|
|
150
|
-
const onError = (err) => {
|
|
151
|
-
if (!resolved) {
|
|
152
|
-
resolved = true;
|
|
153
|
-
if (timeoutHandle)
|
|
154
|
-
clearTimeout(timeoutHandle);
|
|
155
|
-
rejectStart(err);
|
|
156
|
-
}
|
|
157
|
-
};
|
|
158
|
-
server.once('error', onError);
|
|
159
|
-
server.listen(preferredPort, host, () => {
|
|
160
|
-
// Resolve with the actual bound port (important when port=0).
|
|
161
|
-
const addr = server.address();
|
|
162
|
-
const actualPort = addr ? addr.port : preferredPort;
|
|
163
|
-
const waitForCode = () => {
|
|
164
|
-
return new Promise((res, rej) => {
|
|
165
|
-
if (resolved) {
|
|
166
|
-
// Server already resolved (timeout fired, etc.) — reject.
|
|
167
|
-
rej(new OAuthCallbackClosedError());
|
|
168
|
-
return;
|
|
169
|
-
}
|
|
170
|
-
resolveCode = res;
|
|
171
|
-
rejectCode = rej;
|
|
172
|
-
timeoutHandle = setTimeout(() => {
|
|
173
|
-
if (!resolved) {
|
|
174
|
-
resolved = true;
|
|
175
|
-
try {
|
|
176
|
-
server.close();
|
|
177
|
-
}
|
|
178
|
-
catch {
|
|
179
|
-
// ignore
|
|
180
|
-
}
|
|
181
|
-
rej(new OAuthCallbackTimeoutError(timeoutMs));
|
|
182
|
-
}
|
|
183
|
-
}, timeoutMs);
|
|
184
|
-
// Don't keep the process alive just for this timer.
|
|
185
|
-
if (typeof timeoutHandle?.unref === 'function')
|
|
186
|
-
timeoutHandle.unref();
|
|
187
|
-
});
|
|
188
|
-
};
|
|
189
|
-
const close = () => {
|
|
190
|
-
if (timeoutHandle)
|
|
191
|
-
clearTimeout(timeoutHandle);
|
|
192
|
-
try {
|
|
193
|
-
server.close();
|
|
194
|
-
}
|
|
195
|
-
catch {
|
|
196
|
-
// ignore
|
|
197
|
-
}
|
|
198
|
-
if (!resolved && rejectCode) {
|
|
199
|
-
resolved = true;
|
|
200
|
-
rejectCode(new OAuthCallbackClosedError());
|
|
201
|
-
}
|
|
202
|
-
};
|
|
203
|
-
resolveStart({ port: actualPort, waitForCode, close });
|
|
204
|
-
});
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
//# sourceMappingURL=oauthCallbackServer.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"oauthCallbackServer.js","sourceRoot":"","sources":["../../src/cli/oauthCallbackServer.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
import { promises as fs } from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
const REGEX_ESCAPE = /[.+^${}()|[\]\\]/g;
|
|
4
|
-
function escapeRegex(p) {
|
|
5
|
-
return p.replace(REGEX_ESCAPE, '\\$&');
|
|
6
|
-
}
|
|
7
|
-
function globToRegex(glob) {
|
|
8
|
-
// Convert glob pattern to anchored RegExp.
|
|
9
|
-
// Semantics:
|
|
10
|
-
// - `*` → any chars except `/` (one segment)
|
|
11
|
-
// - `**` → any chars including `/` (zero or more segments)
|
|
12
|
-
// - `**/` → zero or more dirs (must be followed by something or end)
|
|
13
|
-
// - `?` → any single char except `/`
|
|
14
|
-
// - `[abc]` → char class
|
|
15
|
-
// - everything else is literal (regex special chars auto-escaped)
|
|
16
|
-
let re = '';
|
|
17
|
-
for (let i = 0; i < glob.length; i++) {
|
|
18
|
-
const c = glob[i];
|
|
19
|
-
if (c === '*') {
|
|
20
|
-
if (glob[i + 1] === '*') {
|
|
21
|
-
if (glob[i + 2] === '/') {
|
|
22
|
-
// **/ → zero or more dirs. Skip both stars AND the slash.
|
|
23
|
-
re += '(?:.*/)?';
|
|
24
|
-
i += 2; // skip second * AND trailing /
|
|
25
|
-
}
|
|
26
|
-
else {
|
|
27
|
-
// ** at end (or **<not-slash>) → match anything
|
|
28
|
-
re += '.*';
|
|
29
|
-
i++; // skip second *
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
// single * → match within one segment
|
|
34
|
-
re += '[^/]*';
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
else if (c === '?') {
|
|
38
|
-
re += '[^/]';
|
|
39
|
-
}
|
|
40
|
-
else if (c === '[') {
|
|
41
|
-
const end = glob.indexOf(']', i);
|
|
42
|
-
if (end === -1) {
|
|
43
|
-
re += escapeRegex(c);
|
|
44
|
-
}
|
|
45
|
-
else {
|
|
46
|
-
re += glob.slice(i, end + 1);
|
|
47
|
-
i = end;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
re += escapeRegex(c);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
return new RegExp('^' + re + '$');
|
|
55
|
-
}
|
|
56
|
-
export function matchesAny(name, patterns) {
|
|
57
|
-
for (const p of patterns) {
|
|
58
|
-
const re = globToRegex(p);
|
|
59
|
-
if (re.test(name))
|
|
60
|
-
return true;
|
|
61
|
-
}
|
|
62
|
-
return false;
|
|
63
|
-
}
|
|
64
|
-
export const DEFAULT_EXCLUDES = [
|
|
65
|
-
'node_modules',
|
|
66
|
-
'.git',
|
|
67
|
-
'dist',
|
|
68
|
-
'build',
|
|
69
|
-
'.next',
|
|
70
|
-
'__pycache__',
|
|
71
|
-
'.cache',
|
|
72
|
-
'.zelari', // v3-W workspace storage (never inspect)
|
|
73
|
-
'.venv',
|
|
74
|
-
'coverage',
|
|
75
|
-
'.nyc_output',
|
|
76
|
-
];
|
|
77
|
-
/**
|
|
78
|
-
* Walk a directory tree, collecting file/dir entries.
|
|
79
|
-
* Mutates {@link entries} in place (avoids large array allocations on deep trees).
|
|
80
|
-
*
|
|
81
|
-
* Depth semantics: depth=0 means "do NOT descend into subdirectories" (root
|
|
82
|
-
* entries only). depth=N means "descend at most N levels below root".
|
|
83
|
-
*
|
|
84
|
-
* The root directory itself is NOT added as an entry.
|
|
85
|
-
*/
|
|
86
|
-
export async function walk(dir, baseRel, depth, maxDepth, exclude, entries, signal) {
|
|
87
|
-
if (depth > maxDepth)
|
|
88
|
-
return;
|
|
89
|
-
if (signal?.aborted)
|
|
90
|
-
return;
|
|
91
|
-
let dirents;
|
|
92
|
-
try {
|
|
93
|
-
dirents = await fs.readdir(dir, { withFileTypes: true });
|
|
94
|
-
}
|
|
95
|
-
catch {
|
|
96
|
-
return; // unreadable subdirectory — skip silently
|
|
97
|
-
}
|
|
98
|
-
if (signal?.aborted)
|
|
99
|
-
return;
|
|
100
|
-
for (const dirent of dirents) {
|
|
101
|
-
if (matchesAny(dirent.name, exclude))
|
|
102
|
-
continue;
|
|
103
|
-
const rel = baseRel ? `${baseRel}/${dirent.name}` : dirent.name;
|
|
104
|
-
const isDir = dirent.isDirectory();
|
|
105
|
-
entries.push({
|
|
106
|
-
name: rel,
|
|
107
|
-
type: isDir ? 'directory' : dirent.isFile() ? 'file' : 'other',
|
|
108
|
-
});
|
|
109
|
-
if (isDir && depth < maxDepth) {
|
|
110
|
-
await walk(path.join(dir, dirent.name), rel, depth + 1, maxDepth, exclude, entries, signal);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* Filter a flat list of FileEntry to those whose relative path matches at
|
|
116
|
-
* least one of {@link include} globs (matched against forward-slash paths).
|
|
117
|
-
*/
|
|
118
|
-
export function filterByInclude(entries, include) {
|
|
119
|
-
if (include.length === 0 || (include.length === 1 && include[0] === '*')) {
|
|
120
|
-
return entries.filter(e => e.type === 'file');
|
|
121
|
-
}
|
|
122
|
-
const regexes = include.map(globToRegex);
|
|
123
|
-
return entries.filter(e => {
|
|
124
|
-
if (e.type !== 'file')
|
|
125
|
-
return false;
|
|
126
|
-
return regexes.some(re => re.test(e.name));
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
//# sourceMappingURL=_walk.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"_walk.js","sourceRoot":"","sources":["../../../../../src/main/core/tools/builtin/_walk.ts"],"names":[],"mappings":"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"}
|