s-app-scoder-agent 0.9.3 → 0.9.7
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 +615 -638
- package/dist/{guardrails.js → agent/guardrails.js} +1 -1
- package/dist/agent/interaction.js +70 -0
- package/dist/agent/mcp-bridge.js +136 -0
- package/dist/agent/prompt-context.js +83 -0
- package/dist/agent/run-loop.js +318 -0
- package/dist/agent/session-persistence.js +61 -0
- package/dist/agent/tool-executor.js +158 -0
- package/dist/agent/types.js +88 -0
- package/dist/agent/verification.js +99 -0
- package/dist/agent.js +239 -1002
- package/dist/cli/args.js +230 -0
- package/dist/cli/init.js +79 -0
- package/dist/cli/main.js +211 -0
- package/dist/cli/mcp-command.js +185 -0
- package/dist/cli/repl.js +77 -0
- package/dist/cli/run-once.js +26 -0
- package/dist/{tui/commands.js → commands/definitions.js} +6 -16
- package/dist/commands/registry.js +260 -0
- package/dist/{config.js → config/config.js} +1 -1
- package/dist/{prompt-builder.js → context/prompt-builder.js} +12 -1
- package/dist/{prompt.js → context/prompt.js} +111 -9
- package/dist/{skills.js → context/skills.js} +41 -2
- package/dist/index.js +5 -798
- package/dist/io/console-reporter.js +24 -0
- package/dist/io/reporter.js +1 -0
- package/dist/mcp/connection.js +227 -0
- package/dist/mcp/env.js +8 -0
- package/dist/{mcp.js → mcp/manager.js} +3 -515
- package/dist/mcp/sse.js +28 -0
- package/dist/mcp/transport-http.js +140 -0
- package/dist/mcp/transport-stdio.js +98 -0
- package/dist/mcp/types.js +11 -0
- package/dist/media/image.js +149 -0
- package/dist/{server.js → server/server.js} +1 -1
- package/dist/{cost.js → session/cost.js} +1 -1
- package/dist/{session.js → session/session.js} +1 -1
- package/dist/{version.js → shared/version.js} +1 -1
- package/dist/tools/apply-patch.js +62 -0
- package/dist/tools/edit-file.js +29 -0
- package/dist/tools/file-edit-common.js +124 -0
- package/dist/tools/list-files.js +64 -0
- package/dist/tools/path-safety.js +75 -0
- package/dist/tools/read-file.js +64 -0
- package/dist/tools/registry.js +297 -0
- package/dist/tools/run-command.js +192 -0
- package/dist/tools/schemas.js +8 -0
- package/dist/tools/search.js +237 -0
- package/dist/tools/task-tool.js +48 -0
- package/dist/tools/types.js +1 -0
- package/dist/tools/write-file.js +34 -0
- package/dist/tui/app.js +59 -532
- package/dist/tui/ask-user-modal.js +2 -1
- package/dist/tui/at-complete.js +2 -93
- package/dist/tui/charset.js +41 -0
- package/dist/tui/chat-views.js +72 -16
- package/dist/tui/chrome.js +11 -5
- package/dist/tui/hooks/use-command-host.js +26 -0
- package/dist/tui/hooks/use-event-queue.js +69 -0
- package/dist/tui/hooks/use-keybinds.js +87 -0
- package/dist/tui/hooks/use-scroll.js +38 -0
- package/dist/tui/hooks/use-session-resume.js +47 -0
- package/dist/tui/hooks/use-submit.js +106 -0
- package/dist/tui/image.js +2 -149
- package/dist/tui/input.js +1 -1
- package/dist/tui/markdown/ast.js +5 -0
- package/dist/tui/markdown/diagram.js +239 -0
- package/dist/tui/markdown/inline-render.js +24 -0
- package/dist/tui/markdown/inline.js +93 -0
- package/dist/tui/markdown/parse.js +139 -0
- package/dist/tui/markdown/render.js +146 -0
- package/dist/tui/markdown/table.js +106 -0
- package/dist/tui/markdown.js +32 -379
- package/dist/tui/permission-modal.js +2 -1
- package/dist/tui/selectors.js +157 -0
- package/dist/tui/session-picker.js +4 -3
- package/dist/tui/sidebar.js +130 -15
- package/dist/tui/state.js +47 -118
- package/dist/tui/text-width.js +139 -0
- package/dist/tui/theme.js +7 -2
- package/dist/{build.js → workspace/build.js} +1 -1
- package/dist/workspace/file-index.js +93 -0
- package/package.json +5 -1
- package/dist/tools.js +0 -1223
- package/dist/tui/command-registry.js +0 -477
- package/dist/tui/review.js +0 -64
- package/dist/tui/transcript.js +0 -145
- /package/dist/{agents-guide.js → context/agents-guide.js} +0 -0
- /package/dist/{agents.js → context/agents.js} +0 -0
- /package/dist/{compaction.js → context/compaction.js} +0 -0
- /package/dist/{context.js → context/context.js} +0 -0
- /package/dist/{memory.js → context/memory.js} +0 -0
- /package/dist/{repo-map.js → context/repo-map.js} +0 -0
- /package/dist/{ui.js → io/terminal.js} +0 -0
- /package/dist/{llm.js → llm/llm.js} +0 -0
- /package/dist/{model-catalog.js → llm/model-catalog.js} +0 -0
- /package/dist/{provider-anthropic.js → llm/provider-anthropic.js} +0 -0
- /package/dist/{provider-registry.js → llm/provider-registry.js} +0 -0
- /package/dist/{retry.js → llm/retry.js} +0 -0
- /package/dist/{mcp-import.js → mcp/mcp-import.js} +0 -0
- /package/dist/{permissions.js → security/permissions.js} +0 -0
- /package/dist/{sandbox.js → security/sandbox.js} +0 -0
- /package/dist/{shell-scanner.js → security/shell-scanner.js} +0 -0
- /package/dist/{logger.js → session/logger.js} +0 -0
- /package/dist/{steering.js → session/steering.js} +0 -0
- /package/dist/{constants.js → shared/constants.js} +0 -0
- /package/dist/{json-schema.js → shared/json-schema.js} +0 -0
- /package/dist/{webfetch.js → tools/webfetch.js} +0 -0
- /package/dist/{diagnostics.js → workspace/diagnostics.js} +0 -0
- /package/dist/{diff.js → workspace/diff.js} +0 -0
- /package/dist/{snapshot.js → workspace/snapshot.js} +0 -0
- /package/dist/{watch.js → workspace/watch.js} +0 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* T-01: `@` fuzzy autocomplete engine — pure logic, TUI-agnostic (unit-testable).
|
|
3
|
+
* Sources: file index (.gitignore-aware via `rg --files`, fallback walk) +
|
|
4
|
+
* directory prefixes so `@src/` opens the subtree. Engine: fuzzysort (MIT).
|
|
5
|
+
*/
|
|
6
|
+
import { spawnSync } from "node:child_process";
|
|
7
|
+
import { readdirSync } from "node:fs";
|
|
8
|
+
import { join, relative } from "node:path";
|
|
9
|
+
import fuzzysort from "fuzzysort";
|
|
10
|
+
const SKIP = new Set(["node_modules", ".git", "dist", "build", ".next", "__pycache__", ".venv"]);
|
|
11
|
+
let cache = null;
|
|
12
|
+
/** File index for `workdir` (cached, TTL 5s; invalidateFileIndex on tool writes). */
|
|
13
|
+
export function fileIndex(workdir) {
|
|
14
|
+
if (cache && Date.now() - cache.built < 5_000)
|
|
15
|
+
return cache.files;
|
|
16
|
+
const files = [];
|
|
17
|
+
// Fast path: ripgrep --files (gitignore-aware). Bare-name globs match at any
|
|
18
|
+
// depth; `!**/x/**` does NOT match absolute paths (I-07 lesson).
|
|
19
|
+
try {
|
|
20
|
+
const r = spawnSync("rg", ["--files", "--hidden", "-g", "!.git", "-g", "!node_modules", "-g", "!dist", "-g", "!build", "-g", "!.venv", "-g", "!__pycache__", "-g", "!.next", "--no-messages", workdir], { maxBuffer: 16e6, timeout: 3_000 });
|
|
21
|
+
if (r.status === 0) {
|
|
22
|
+
for (const line of r.stdout.toString().split("\n")) {
|
|
23
|
+
if (line)
|
|
24
|
+
files.push(relative(workdir, line) || line);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// no rg on PATH → walker fallback
|
|
30
|
+
}
|
|
31
|
+
if (files.length === 0)
|
|
32
|
+
walkFiles(workdir, "", files, 0);
|
|
33
|
+
files.sort();
|
|
34
|
+
cache = { files, built: Date.now() };
|
|
35
|
+
return files;
|
|
36
|
+
}
|
|
37
|
+
/** Cache invalidate — call after write/edit tool_result (scope: whole index). */
|
|
38
|
+
export function invalidateFileIndex() {
|
|
39
|
+
cache = null;
|
|
40
|
+
}
|
|
41
|
+
function walkFiles(root, prefix, out, depth) {
|
|
42
|
+
if (depth > 6)
|
|
43
|
+
return;
|
|
44
|
+
let entries;
|
|
45
|
+
try {
|
|
46
|
+
entries = readdirSync(root, { withFileTypes: true });
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
for (const e of entries) {
|
|
52
|
+
if (SKIP.has(e.name))
|
|
53
|
+
continue;
|
|
54
|
+
const rel = prefix ? `${prefix}/${e.name}` : e.name;
|
|
55
|
+
if (e.isDirectory())
|
|
56
|
+
walkFiles(join(root, e.name), rel, out, depth + 1);
|
|
57
|
+
else if (e.isFile())
|
|
58
|
+
out.push(rel);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/** Active `@` token in `value`, or null. Returns start index (of "@") + query. */
|
|
62
|
+
export function atQuery(value) {
|
|
63
|
+
const m = /(^|\s)@([^\s@]*)$/.exec(value);
|
|
64
|
+
if (!m)
|
|
65
|
+
return null;
|
|
66
|
+
return { start: m.index + m[1].length, query: m[2] };
|
|
67
|
+
}
|
|
68
|
+
/** Candidate suggestions for a query: fuzzy files + dir prefixes, max 8. */
|
|
69
|
+
export function suggest(files, query, limit = 8) {
|
|
70
|
+
const dirs = new Set();
|
|
71
|
+
for (const f of files) {
|
|
72
|
+
const parts = f.split("/");
|
|
73
|
+
for (let i = 1; i < parts.length; i++)
|
|
74
|
+
dirs.add(parts.slice(0, i).join("/"));
|
|
75
|
+
}
|
|
76
|
+
const all = [...files, ...[...dirs].map((d) => `${d}/`)];
|
|
77
|
+
let hits;
|
|
78
|
+
if (query.includes("/") || query.endsWith("/")) {
|
|
79
|
+
// Subtree mode: prefix match on directories (`@src/tui/…`).
|
|
80
|
+
hits = all.filter((t) => t.startsWith(query));
|
|
81
|
+
}
|
|
82
|
+
else if (query === "") {
|
|
83
|
+
hits = all.slice(0, limit * 4);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
hits = fuzzysort.go(query, all, { limit: limit * 4 }).map((r) => r.target);
|
|
87
|
+
}
|
|
88
|
+
return hits.slice(0, limit);
|
|
89
|
+
}
|
|
90
|
+
/** Replace the active @token with `sel` (dirs keep the trailing slash). */
|
|
91
|
+
export function applySuggestion(value, at, sel) {
|
|
92
|
+
return value.slice(0, at.start) + "@" + sel + (sel.endsWith("/") ? "" : " ");
|
|
93
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "s-app-scoder-agent",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.7",
|
|
4
4
|
"description": "Autonomous coding agent CLI — writes, edits, and builds code autonomously until the project compiles without errors.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -15,6 +15,9 @@
|
|
|
15
15
|
"dev": "tsc --watch",
|
|
16
16
|
"typecheck": "tsc --noEmit",
|
|
17
17
|
"lint": "eslint src/",
|
|
18
|
+
"check:layers": "node scripts/check-layers.mjs",
|
|
19
|
+
"check:layers:graph": "node scripts/check-layers.mjs --graph",
|
|
20
|
+
"docs:check": "node scripts/check-docs.mjs",
|
|
18
21
|
"coverage": "npm run build && node --test --experimental-test-coverage test/*.test.mjs",
|
|
19
22
|
"eval": "node test/run-eval.mjs",
|
|
20
23
|
"test": "npm run build && node --test test/*.test.mjs && node test/run-e2e.mjs && node test/run-mcp-test.mjs"
|
|
@@ -60,6 +63,7 @@
|
|
|
60
63
|
"ink": "^8.0.0",
|
|
61
64
|
"react": "^19.3.1",
|
|
62
65
|
"react-dom": "^19.3.1",
|
|
66
|
+
"string-width": "^8.3.0",
|
|
63
67
|
"tree-sitter": "^0.25.1",
|
|
64
68
|
"tree-sitter-bash": "^0.25.1"
|
|
65
69
|
}
|