indusagi-coding-agent 0.2.13 → 0.2.14
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 +19 -0
- package/dist/entry.js +1762 -958
- package/dist/guardrails.js +145 -35
- package/dist/index.js +1810 -1006
- package/dist/review-agent.js +344 -60
- package/dist/review-server.js +346 -62
- package/package.json +12 -3
- package/src/boot/auth-vault.ts +4 -5
- package/src/boot/runners/addon-wiring.ts +111 -3
- package/src/boot/runners/benchmark-integrity.ts +107 -0
- package/src/boot/runners/repl-runner.ts +2 -1
- package/src/boot/runners/session.ts +18 -8
- package/src/boot/server-token.ts +20 -11
- package/src/briefing/context-docs.ts +144 -12
- package/src/channels/oneshot.ts +6 -0
- package/src/conductor/conductor.ts +67 -12
- package/src/conductor/contract.ts +4 -3
- package/src/conductor/transcript-store/store.ts +4 -8
- package/src/console/auth-status.ts +9 -4
- package/src/console/components/AgentsView.ts +2 -2
- package/src/console/components/BackgroundAgents.ts +15 -2
- package/src/console/components/Banner.ts +20 -9
- package/src/console/components/Composer.ts +57 -82
- package/src/console/components/ScrollViewport.ts +46 -0
- package/src/console/components/TerminalConsole.ts +165 -162
- package/src/console/components/WorkingIndicator.ts +6 -5
- package/src/console/components/banner-sweep.ts +5 -1
- package/src/console/components/welcome.ts +3 -3
- package/src/console/contract.ts +10 -5
- package/src/console/index.ts +7 -7
- package/src/console/input/complete.ts +2 -2
- package/src/console/input/dir-reader.ts +3 -1
- package/src/console/input/graphemes.ts +22 -0
- package/src/console/input/keymap.ts +6 -4
- package/src/console/mount.ts +45 -3
- package/src/console/overlays/auth.ts +28 -8
- package/src/console/overlays/boards.ts +13 -40
- package/src/console/overlays/host.ts +10 -0
- package/src/console/overlays/pickers.ts +35 -30
- package/src/console/reducer.ts +12 -5
- package/src/console/slash/builtins.ts +4 -3
- package/src/console/slash/commands/integrations.ts +13 -14
- package/src/console/slash/commands/transcript.ts +3 -8
- package/src/console/slash/commands/workbench.ts +2 -2
- package/src/console/test-support.ts +48 -0
- package/src/integrations/sarvam/config.ts +15 -13
- package/src/kit/external-editor.ts +17 -1
- package/src/kit/run-shell.ts +31 -0
- package/src/launch/invocation/flags.ts +12 -0
- package/src/launch/login.ts +23 -10
- package/src/launch/oauth.ts +3 -0
- package/src/models.ts +78 -2
- package/src/security/private-state.ts +122 -0
- package/src/window-budget/summarize/condense.ts +4 -1
- package/src/workspace/brand.ts +1 -1
- package/src/workspace/locator.ts +2 -2
package/dist/guardrails.js
CHANGED
|
@@ -812,49 +812,52 @@ function composeBriefing(input) {
|
|
|
812
812
|
}
|
|
813
813
|
|
|
814
814
|
// src/briefing/context-docs.ts
|
|
815
|
-
import {
|
|
816
|
-
import { dirname, extname, isAbsolute, join, parse, resolve } from "node:path";
|
|
815
|
+
import { closeSync, constants, fstatSync, lstatSync, openSync, readFileSync, realpathSync } from "node:fs";
|
|
816
|
+
import { basename, dirname, extname, isAbsolute, join, parse, resolve, sep } from "node:path";
|
|
817
817
|
var DEFAULT_MAX_IMPORT_DEPTH = 5;
|
|
818
818
|
var DEFAULT_MAX_BYTES_PER_DOC = 4e4;
|
|
819
819
|
var CANDIDATE_FILES = ["AGENTS.md", "CLAUDE.md", "INDUSAGI.md", "CLAUDE.local.md", "AGENTS.local.md", join(".indusagi", "CLAUDE.md"), join(".claude", "CLAUDE.md")];
|
|
820
|
-
var TEXT_FILE_EXTENSIONS = /* @__PURE__ */ new Set([".md", ".markdown", ".txt", ".text", ".json", ".jsonc", ".yaml", ".yml", ".toml", ".xml", ".csv", ".html", ".htm", ".css", ".js", ".ts", ".tsx", ".jsx", ".mjs", ".cjs", ".mts", ".cts", ".py", ".rb", ".go", ".rs", ".sh"
|
|
820
|
+
var TEXT_FILE_EXTENSIONS = /* @__PURE__ */ new Set([".md", ".markdown", ".txt", ".text", ".json", ".jsonc", ".yaml", ".yml", ".toml", ".xml", ".csv", ".html", ".htm", ".css", ".js", ".ts", ".tsx", ".jsx", ".mjs", ".cjs", ".mts", ".cts", ".py", ".rb", ".go", ".rs", ".sh"]);
|
|
821
821
|
var IMPORT_REGEX = /(?:^|\s)@((?:[^\s\\]|\\ )+)/g;
|
|
822
|
+
var NO_FOLLOW = constants.O_NOFOLLOW ?? 0;
|
|
823
|
+
var SECRET_BASENAMES = /* @__PURE__ */ new Set([
|
|
824
|
+
".env",
|
|
825
|
+
"credentials",
|
|
826
|
+
"credentials.json",
|
|
827
|
+
"id_rsa",
|
|
828
|
+
"id_dsa",
|
|
829
|
+
"id_ecdsa",
|
|
830
|
+
"id_ed25519"
|
|
831
|
+
]);
|
|
832
|
+
var SECRET_EXTENSIONS = /* @__PURE__ */ new Set([".key", ".pem", ".p12", ".pfx"]);
|
|
822
833
|
function shortenPath(path, cwd, home) {
|
|
823
|
-
if (cwd && path.startsWith(cwd)) {
|
|
834
|
+
if (cwd && (path === cwd || path.startsWith(`${cwd}${sep}`))) {
|
|
824
835
|
const rest = path.slice(cwd.length).replace(/^[/\\]+/, "");
|
|
825
836
|
return rest ? `./${rest}` : ".";
|
|
826
837
|
}
|
|
827
|
-
return home && path.startsWith(home) ? `~${path.slice(home.length)}` : path;
|
|
828
|
-
}
|
|
829
|
-
function dirChain(cwd) {
|
|
830
|
-
const chain = [];
|
|
831
|
-
let current = cwd;
|
|
832
|
-
for (let i = 0; i < 256; i++) {
|
|
833
|
-
chain.push(current);
|
|
834
|
-
const parent = dirname(current);
|
|
835
|
-
if (parent === current || current === parse(current).root) break;
|
|
836
|
-
current = parent;
|
|
837
|
-
}
|
|
838
|
-
return chain.reverse();
|
|
839
|
-
}
|
|
840
|
-
function safeRealpath(path) {
|
|
841
|
-
try {
|
|
842
|
-
return realpathSync(path);
|
|
843
|
-
} catch {
|
|
844
|
-
return path;
|
|
845
|
-
}
|
|
838
|
+
return home && (path === home || path.startsWith(`${home}${sep}`)) ? `~${path.slice(home.length)}` : path;
|
|
846
839
|
}
|
|
847
840
|
function isTextFile(path) {
|
|
848
841
|
const extension = extname(path).toLowerCase();
|
|
849
842
|
return !extension || TEXT_FILE_EXTENSIONS.has(extension);
|
|
850
843
|
}
|
|
844
|
+
function isLikelySecretFile(path) {
|
|
845
|
+
const name = basename(path).toLowerCase();
|
|
846
|
+
return SECRET_BASENAMES.has(name) || name.startsWith(".env.") || SECRET_EXTENSIONS.has(extname(name));
|
|
847
|
+
}
|
|
851
848
|
function readFileBody(path) {
|
|
852
|
-
|
|
849
|
+
let fd;
|
|
853
850
|
try {
|
|
854
|
-
const
|
|
851
|
+
const before = lstatSync(path);
|
|
852
|
+
if (before.isSymbolicLink() || !before.isFile()) return null;
|
|
853
|
+
fd = openSync(path, constants.O_RDONLY | NO_FOLLOW);
|
|
854
|
+
if (!fstatSync(fd).isFile()) return null;
|
|
855
|
+
const body = readFileSync(fd, "utf8").trim();
|
|
855
856
|
return body || null;
|
|
856
857
|
} catch {
|
|
857
858
|
return null;
|
|
859
|
+
} finally {
|
|
860
|
+
if (fd !== void 0) closeSync(fd);
|
|
858
861
|
}
|
|
859
862
|
}
|
|
860
863
|
function extractImports(body, baseDir, home) {
|
|
@@ -873,23 +876,46 @@ function extractImports(body, baseDir, home) {
|
|
|
873
876
|
}
|
|
874
877
|
return out;
|
|
875
878
|
}
|
|
876
|
-
function
|
|
877
|
-
|
|
878
|
-
|
|
879
|
+
function canonicalExistingFile(path) {
|
|
880
|
+
try {
|
|
881
|
+
const before = lstatSync(path);
|
|
882
|
+
if (before.isSymbolicLink() || !before.isFile()) return null;
|
|
883
|
+
return realpathSync(path);
|
|
884
|
+
} catch {
|
|
885
|
+
return null;
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
function isWithin(root, candidate) {
|
|
889
|
+
return candidate === root || candidate.startsWith(`${root}${sep}`);
|
|
890
|
+
}
|
|
891
|
+
function loadTrustedDocTree(path, cwd, home, seen, depth, maxDepth, maxBytes, out, policy) {
|
|
892
|
+
if (isLikelySecretFile(path)) return;
|
|
893
|
+
const real = canonicalExistingFile(path);
|
|
894
|
+
if (real === null || seen.has(real) || isLikelySecretFile(real)) return;
|
|
895
|
+
if (!isWithin(policy.root, real) && !policy.approvedExternal.has(real)) return;
|
|
879
896
|
seen.add(real);
|
|
880
|
-
const body = readFileBody(
|
|
897
|
+
const body = readFileBody(real);
|
|
881
898
|
if (body === null) return;
|
|
882
|
-
out.push({ path: shortenPath(
|
|
899
|
+
out.push({ path: shortenPath(real, cwd, home), body: body.length > maxBytes ? body.slice(0, maxBytes) : body });
|
|
883
900
|
if (depth >= maxDepth) return;
|
|
884
|
-
for (const child of extractImports(body, dirname(
|
|
901
|
+
for (const child of extractImports(body, dirname(real), home)) {
|
|
902
|
+
loadTrustedDocTree(child, cwd, home, seen, depth + 1, maxDepth, maxBytes, out, policy);
|
|
903
|
+
}
|
|
885
904
|
}
|
|
886
|
-
function gatherContextDocs(cwd, home, opts) {
|
|
905
|
+
function gatherContextDocs(cwd, home, opts = {}) {
|
|
887
906
|
const out = [];
|
|
888
907
|
try {
|
|
908
|
+
const root = realpathSync(cwd);
|
|
909
|
+
const approvedExternal = /* @__PURE__ */ new Set();
|
|
910
|
+
for (const path of opts.approvedExternalPaths ?? []) {
|
|
911
|
+
const real = canonicalExistingFile(path);
|
|
912
|
+
if (real !== null && !isLikelySecretFile(real)) approvedExternal.add(real);
|
|
913
|
+
}
|
|
914
|
+
const policy = { root, approvedExternal };
|
|
889
915
|
const seen = /* @__PURE__ */ new Set();
|
|
890
|
-
const
|
|
891
|
-
|
|
892
|
-
|
|
916
|
+
for (const name of CANDIDATE_FILES) {
|
|
917
|
+
loadTrustedDocTree(join(root, name), root, home, seen, 0, opts.maxImportDepth ?? DEFAULT_MAX_IMPORT_DEPTH, opts.maxBytesPerDoc ?? DEFAULT_MAX_BYTES_PER_DOC, out, policy);
|
|
918
|
+
}
|
|
893
919
|
} catch {
|
|
894
920
|
return out;
|
|
895
921
|
}
|
|
@@ -2025,7 +2051,74 @@ var GPT_6_ASTRA_BASE = {
|
|
|
2025
2051
|
}
|
|
2026
2052
|
}
|
|
2027
2053
|
};
|
|
2054
|
+
var GPT_6_SOL_BASE = {
|
|
2055
|
+
id: "gpt-6-sol",
|
|
2056
|
+
name: "GPT-6 Sol",
|
|
2057
|
+
api: "openai-responses",
|
|
2058
|
+
reasoning: true,
|
|
2059
|
+
reasoningEfforts: ["high"],
|
|
2060
|
+
input: ["text", "image"],
|
|
2061
|
+
cost: {
|
|
2062
|
+
input: 10,
|
|
2063
|
+
cacheRead: 1,
|
|
2064
|
+
cacheWrite: 12.5,
|
|
2065
|
+
output: 50
|
|
2066
|
+
},
|
|
2067
|
+
contextWindow: 105e4,
|
|
2068
|
+
maxTokens: 128e3,
|
|
2069
|
+
longContextPricing: {
|
|
2070
|
+
threshold: 272e3,
|
|
2071
|
+
multipliers: {
|
|
2072
|
+
input: 2,
|
|
2073
|
+
cacheRead: 2,
|
|
2074
|
+
cacheWrite: 2,
|
|
2075
|
+
output: 1.5
|
|
2076
|
+
}
|
|
2077
|
+
}
|
|
2078
|
+
};
|
|
2079
|
+
var GPT_6_LUNA_BASE = {
|
|
2080
|
+
id: "gpt-6-luna",
|
|
2081
|
+
name: "GPT-6 Luna",
|
|
2082
|
+
api: "openai-responses",
|
|
2083
|
+
reasoning: true,
|
|
2084
|
+
reasoningEfforts: ["low", "medium", "high", "xhigh", "max"],
|
|
2085
|
+
input: ["text", "image"],
|
|
2086
|
+
cost: {
|
|
2087
|
+
input: 0.1,
|
|
2088
|
+
cacheRead: 0.01,
|
|
2089
|
+
cacheWrite: 0.125,
|
|
2090
|
+
output: 0.5
|
|
2091
|
+
},
|
|
2092
|
+
contextWindow: 105e4,
|
|
2093
|
+
maxTokens: 128e3,
|
|
2094
|
+
longContextPricing: {
|
|
2095
|
+
threshold: 272e3,
|
|
2096
|
+
multipliers: { input: 2, cacheRead: 2, cacheWrite: 2, output: 1.5 }
|
|
2097
|
+
}
|
|
2098
|
+
};
|
|
2028
2099
|
var CODING_AGENT_MODELS = [
|
|
2100
|
+
{
|
|
2101
|
+
...GPT_6_SOL_BASE,
|
|
2102
|
+
provider: "openai",
|
|
2103
|
+
baseUrl: "https://api.openai.com/v1"
|
|
2104
|
+
},
|
|
2105
|
+
{
|
|
2106
|
+
...GPT_6_SOL_BASE,
|
|
2107
|
+
api: "openai-codex-responses",
|
|
2108
|
+
provider: "openai-codex",
|
|
2109
|
+
baseUrl: "https://chatgpt.com/backend-api"
|
|
2110
|
+
},
|
|
2111
|
+
{
|
|
2112
|
+
...GPT_6_LUNA_BASE,
|
|
2113
|
+
provider: "openai",
|
|
2114
|
+
baseUrl: "https://api.openai.com/v1"
|
|
2115
|
+
},
|
|
2116
|
+
{
|
|
2117
|
+
...GPT_6_LUNA_BASE,
|
|
2118
|
+
api: "openai-codex-responses",
|
|
2119
|
+
provider: "openai-codex",
|
|
2120
|
+
baseUrl: "https://chatgpt.com/backend-api"
|
|
2121
|
+
},
|
|
2029
2122
|
{
|
|
2030
2123
|
...GPT_6_ASTRA_BASE,
|
|
2031
2124
|
provider: "openai",
|
|
@@ -2081,6 +2174,23 @@ import { ulid } from "ulid";
|
|
|
2081
2174
|
// src/conductor/transcript-store/serialize.ts
|
|
2082
2175
|
import { buildSessionContext, convertToLlm, loadEntriesFromFile, parseSessionEntries } from "indusagi/agent";
|
|
2083
2176
|
|
|
2177
|
+
// src/security/private-state.ts
|
|
2178
|
+
import {
|
|
2179
|
+
chmodSync,
|
|
2180
|
+
closeSync as closeSync2,
|
|
2181
|
+
constants as constants2,
|
|
2182
|
+
fchmodSync,
|
|
2183
|
+
fstatSync as fstatSync2,
|
|
2184
|
+
lstatSync as lstatSync2,
|
|
2185
|
+
mkdirSync as mkdirSync2,
|
|
2186
|
+
openSync as openSync2,
|
|
2187
|
+
readFileSync as readFileSync2,
|
|
2188
|
+
renameSync,
|
|
2189
|
+
rmSync as rmSync2,
|
|
2190
|
+
writeFileSync as writeFileSync2
|
|
2191
|
+
} from "node:fs";
|
|
2192
|
+
var NO_FOLLOW2 = constants2.O_NOFOLLOW ?? 0;
|
|
2193
|
+
|
|
2084
2194
|
// src/window-budget/summarize/prompt.ts
|
|
2085
2195
|
var CONDENSER_BRIEF = [
|
|
2086
2196
|
"You are a transcript recorder for a long-running coding session.",
|