@gajae-code/coding-agent 0.16.3 → 0.16.4
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/CHANGELOG.md +59 -0
- package/dist/types/cli/args.d.ts +2 -2
- package/dist/types/cli/root-flags.d.ts +4 -2
- package/dist/types/cli.d.ts +1 -1
- package/dist/types/commands/launch.d.ts +1 -1
- package/dist/types/config/autorouting-tier-map.d.ts +3 -0
- package/dist/types/config/model-registry.d.ts +4 -0
- package/dist/types/config/model-resolver.d.ts +9 -0
- package/dist/types/config/settings-schema.d.ts +29 -1
- package/dist/types/discovery/claude-plugins.d.ts +3 -1
- package/dist/types/discovery/helpers.d.ts +2 -0
- package/dist/types/extensibility/gjc-plugins/mcp-policy.d.ts +16 -0
- package/dist/types/extensibility/gjc-plugins/paths.d.ts +2 -0
- package/dist/types/extensibility/runtime-skill-discovery.d.ts +1 -1
- package/dist/types/extensibility/shared-events.d.ts +1 -1
- package/dist/types/gjc-runtime/session-state-lock.d.ts +2 -0
- package/dist/types/modes/components/assistant-message.d.ts +1 -2
- package/dist/types/modes/components/settings-selector.d.ts +6 -1
- package/dist/types/modes/components/status-line/command.d.ts +35 -0
- package/dist/types/modes/components/status-line/index.d.ts +1 -0
- package/dist/types/modes/components/status-line/types.d.ts +5 -0
- package/dist/types/modes/components/tool-status-header.d.ts +14 -0
- package/dist/types/modes/controllers/event-controller.d.ts +6 -0
- package/dist/types/modes/interactive-mode.d.ts +1 -0
- package/dist/types/modes/types.d.ts +1 -0
- package/dist/types/runtime-mcp/client.d.ts +9 -1
- package/dist/types/runtime-mcp/manager.d.ts +7 -1
- package/dist/types/runtime-mcp/pool.d.ts +22 -3
- package/dist/types/runtime-mcp/transports/stdio.d.ts +0 -4
- package/dist/types/runtime-mcp/types.d.ts +22 -0
- package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +12 -0
- package/dist/types/sdk/bus/slack-live-provider.d.ts +6 -0
- package/dist/types/sdk/bus/slack-provider.d.ts +12 -0
- package/dist/types/sdk/host/session-runtime.d.ts +23 -0
- package/dist/types/sdk/session-api-key.d.ts +26 -0
- package/dist/types/sdk/transport/serve-cli.d.ts +1 -1
- package/dist/types/session/agent-session.d.ts +9 -0
- package/dist/types/setup/paseo/announce.d.ts +111 -0
- package/dist/types/setup/paseo/setup-deps.d.ts +2 -1
- package/dist/types/system-prompt.d.ts +2 -0
- package/dist/types/task/executor.d.ts +2 -1
- package/dist/types/tools/fetch.d.ts +7 -0
- package/dist/types/tools/index.d.ts +8 -0
- package/dist/types/tools/path-utils.d.ts +2 -0
- package/dist/types/tools/search.d.ts +6 -0
- package/package.json +7 -7
- package/scripts/capture-status-line-custom-editor-showcase.ts +151 -0
- package/scripts/generate-sdk-operation-inventory.ts +9 -0
- package/scripts/verify-status-line-custom-editor-showcase.ts +309 -0
- package/src/cli/args.ts +20 -9
- package/src/cli/root-flags.ts +5 -3
- package/src/config/autorouting-tier-map.ts +1 -0
- package/src/config/file-lock.ts +181 -17
- package/src/config/model-preset-registry.ts +5 -3
- package/src/config/model-profiles.ts +40 -0
- package/src/config/model-registry.ts +57 -11
- package/src/config/model-resolver.ts +48 -0
- package/src/config/settings-schema.ts +33 -1
- package/src/config/settings.ts +1 -0
- package/src/defaults/gjc/extensions/grok-cli-vendor/src/models/catalog.ts +11 -11
- package/src/defaults/gjc/extensions/grok-cli-vendor/src/provider/register.ts +13 -2
- package/src/discovery/builtin.ts +13 -4
- package/src/discovery/claude-plugins.ts +12 -4
- package/src/discovery/helpers.ts +10 -2
- package/src/extensibility/gjc-plugins/compiler.ts +208 -58
- package/src/extensibility/gjc-plugins/installer.ts +13 -12
- package/src/extensibility/gjc-plugins/mcp-policy.ts +81 -52
- package/src/extensibility/gjc-plugins/paths.ts +13 -0
- package/src/extensibility/gjc-plugins/runtime-adapters.ts +758 -16
- package/src/extensibility/runtime-skill-discovery.ts +77 -151
- package/src/extensibility/shared-events.ts +1 -1
- package/src/extensibility/skills.ts +44 -16
- package/src/gjc-runtime/repository-binding.ts +1 -1
- package/src/gjc-runtime/session-state-lock.ts +92 -2
- package/src/internal-urls/docs-index.generated.ts +7 -7
- package/src/main.ts +72 -34
- package/src/modes/DESIGN.md +54 -0
- package/src/modes/components/assistant-message.ts +22 -9
- package/src/modes/components/model-selector.ts +166 -33
- package/src/modes/components/settings-selector.ts +1075 -235
- package/src/modes/components/status-line/command.ts +190 -0
- package/src/modes/components/status-line/index.ts +1 -0
- package/src/modes/components/status-line/segments.ts +32 -5
- package/src/modes/components/status-line/types.ts +5 -0
- package/src/modes/components/tool-status-header.ts +393 -21
- package/src/modes/controllers/command-controller.ts +2 -0
- package/src/modes/controllers/event-controller.ts +148 -5
- package/src/modes/controllers/selector-controller.ts +21 -0
- package/src/modes/interactive-mode.ts +47 -1
- package/src/modes/types.ts +1 -0
- package/src/modes/utils/ui-helpers.ts +1 -0
- package/src/prompts/system/system-prompt.md +8 -0
- package/src/prompts/tools/search.md +2 -0
- package/src/runtime-mcp/client.ts +60 -17
- package/src/runtime-mcp/manager.ts +171 -14
- package/src/runtime-mcp/pool.test.ts +209 -0
- package/src/runtime-mcp/pool.ts +224 -23
- package/src/runtime-mcp/transports/stdio.ts +158 -24
- package/src/runtime-mcp/types.ts +24 -0
- package/src/sdk/broker/broker.ts +5 -4
- package/src/sdk/bus/chat-daemon-control.ts +1 -1
- package/src/sdk/bus/chat-daemon-runtime.ts +37 -1
- package/src/sdk/bus/slack-daemon.ts +92 -2
- package/src/sdk/bus/slack-live-provider.ts +12 -0
- package/src/sdk/bus/slack-provider.ts +5 -0
- package/src/sdk/cli/session-cli.ts +9 -6
- package/src/sdk/host/session-runtime.test.ts +2 -2
- package/src/sdk/host/session-runtime.ts +275 -43
- package/src/sdk/protocol/operation-inventory.generated.json +66 -0
- package/src/sdk/session-api-key.ts +94 -0
- package/src/sdk/session.ts +73 -29
- package/src/sdk/transport/serve-cli.ts +3 -3
- package/src/session/agent-session.ts +123 -38
- package/src/session/contribution-prep.ts +214 -21
- package/src/setup/paseo/announce.ts +450 -0
- package/src/setup/paseo/setup-deps.ts +15 -3
- package/src/slash-commands/builtin-registry.ts +1 -0
- package/src/system-prompt.ts +4 -0
- package/src/task/executor.ts +2 -1
- package/src/task/index.ts +17 -4
- package/src/tools/bash.ts +35 -8
- package/src/tools/cron.ts +1 -1
- package/src/tools/fetch.ts +29 -1
- package/src/tools/index.ts +8 -0
- package/src/tools/job.ts +8 -2
- package/src/tools/monitor.ts +8 -2
- package/src/tools/path-utils.ts +7 -0
- package/src/tools/search.ts +116 -58
- package/src/tools/skill.ts +22 -2
- package/src/tools/subagent.ts +3 -1
- package/src/tools/tool-catalog.generated.ts +8 -1
- package/src/web/insane/bridge.ts +113 -23
- package/src/web/search/providers/perplexity.ts +102 -41
|
@@ -158,69 +158,98 @@ export interface StdioPolicyContext {
|
|
|
158
158
|
pluginRoot: string;
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
"
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
"--loader",
|
|
171
|
-
"--experimental-loader",
|
|
172
|
-
"--input-type",
|
|
173
|
-
];
|
|
161
|
+
export interface StdioInvocationTarget {
|
|
162
|
+
kind: "launcher";
|
|
163
|
+
launcher: "node" | "bun";
|
|
164
|
+
entrypoint: string;
|
|
165
|
+
executablePath: string;
|
|
166
|
+
ownedRelativePath: string;
|
|
167
|
+
ownedRelativePaths: string[];
|
|
168
|
+
cwd: string;
|
|
169
|
+
}
|
|
174
170
|
|
|
175
|
-
|
|
176
|
-
|
|
171
|
+
function isWithinOrEqual(root: string, candidate: string): boolean {
|
|
172
|
+
return candidate === root || pathIsWithin(root, candidate);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function isCrossPlatformAbsolute(value: string): boolean {
|
|
176
|
+
return path.posix.isAbsolute(value) || path.win32.isAbsolute(value) || /^[A-Za-z]:/.test(value);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function resolveManifestRelative(base: string, value: string, label: string): string {
|
|
180
|
+
if (isCrossPlatformAbsolute(value)) fail(`${label} must be relative`);
|
|
181
|
+
const portable = path.posix.normalize(value.replaceAll("\\", "/"));
|
|
182
|
+
return path.resolve(base, ...portable.split("/"));
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function isFileLikeArgument(value: string): boolean {
|
|
186
|
+
return value.startsWith(".") || value.includes("/") || value.includes("\\") || isCrossPlatformAbsolute(value);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Resolve the exact executable file selected by the supported stdio grammar.
|
|
191
|
+
* Bare Node/Bun launchers accept a direct bundled entrypoint as argv[0]; no
|
|
192
|
+
* manifest-controlled runtime options or subcommands precede it. Path-qualified
|
|
193
|
+
* commands are unsupported because they bypass the verified module wrapper.
|
|
194
|
+
*/
|
|
195
|
+
export function classifyStdioInvocation(
|
|
196
|
+
entry: GjcPluginMcpManifestEntry,
|
|
197
|
+
ctx: StdioPolicyContext,
|
|
198
|
+
): StdioInvocationTarget {
|
|
177
199
|
const command = entry.command ?? "";
|
|
178
200
|
if (!command) fail(`MCP "${entry.name}": stdio requires a command`);
|
|
179
201
|
const root = path.resolve(ctx.pluginRoot);
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
const isRootConfinedExecutable = command.includes("/") && pathIsWithin(root, path.resolve(root, command));
|
|
183
|
-
// Absolute or relative paths must stay inside the plugin root; bare launchers
|
|
184
|
-
// must be in the allowlist. An absolute /bin/node is rejected (outside root).
|
|
185
|
-
if (!isBareLauncher && !isRootConfinedExecutable) {
|
|
186
|
-
fail(`MCP "${entry.name}": stdio command not allowed: ${command}`);
|
|
187
|
-
}
|
|
188
|
-
const usesNodeLauncher = isBareLauncher || ALLOWED_STDIO_LAUNCHERS.has(base);
|
|
189
|
-
const args = entry.args ?? [];
|
|
190
|
-
// Reject code-eval/loader flags for node/bun launchers.
|
|
191
|
-
if (usesNodeLauncher) {
|
|
192
|
-
for (const arg of args) {
|
|
193
|
-
const flag = arg.split("=")[0];
|
|
194
|
-
if (DANGEROUS_LAUNCHER_FLAGS.includes(flag)) {
|
|
195
|
-
fail(`MCP "${entry.name}": stdio launcher flag not allowed: ${arg}`);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
// Require a root-confined script as the first non-flag argument.
|
|
199
|
-
const firstScript = args.find(a => !a.startsWith("-"));
|
|
200
|
-
if (!firstScript) {
|
|
201
|
-
fail(`MCP "${entry.name}": node/bun stdio launcher requires a bundled script argument`);
|
|
202
|
-
}
|
|
203
|
-
if (!pathIsWithin(root, path.resolve(root, firstScript))) {
|
|
204
|
-
fail(`MCP "${entry.name}": stdio script escapes plugin root: ${firstScript}`);
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
// cwd must resolve within the plugin root.
|
|
208
|
-
const cwd = entry.cwd ? path.resolve(root, entry.cwd) : root;
|
|
209
|
-
if (!pathIsWithin(root, cwd) && cwd !== root) {
|
|
202
|
+
const cwd = entry.cwd ? resolveManifestRelative(root, entry.cwd, `MCP "${entry.name}": stdio cwd`) : root;
|
|
203
|
+
if (!isWithinOrEqual(root, cwd)) {
|
|
210
204
|
fail(`MCP "${entry.name}": stdio cwd escapes plugin root: ${entry.cwd}`);
|
|
211
205
|
}
|
|
212
|
-
|
|
206
|
+
const args = entry.args ?? [];
|
|
213
207
|
for (const arg of args) {
|
|
214
208
|
if (/\$\{?[A-Za-z_]/.test(arg) || arg.includes("`") || arg.includes("$(")) {
|
|
215
209
|
fail(`MCP "${entry.name}": stdio arg expansion not allowed: ${arg}`);
|
|
216
210
|
}
|
|
217
|
-
if (arg.startsWith("-")) continue;
|
|
218
|
-
if (!arg.startsWith(".") && !arg.includes("/")) continue;
|
|
219
|
-
const resolvedArg = path.resolve(root, arg);
|
|
220
|
-
if (!pathIsWithin(root, resolvedArg)) {
|
|
221
|
-
fail(`MCP "${entry.name}": stdio arg escapes plugin root: ${arg}`);
|
|
222
|
-
}
|
|
223
211
|
}
|
|
212
|
+
|
|
213
|
+
if (!ALLOWED_STDIO_LAUNCHERS.has(command)) {
|
|
214
|
+
fail(`MCP "${entry.name}": stdio command not allowed (expected bare node or bun): ${command}`);
|
|
215
|
+
}
|
|
216
|
+
const entrypoint = args[0];
|
|
217
|
+
if (!entrypoint) {
|
|
218
|
+
fail(`MCP "${entry.name}": node/bun stdio launcher requires a bundled script argument`);
|
|
219
|
+
}
|
|
220
|
+
if (entrypoint.startsWith("-")) {
|
|
221
|
+
fail(`MCP "${entry.name}": stdio launcher options before the bundled entrypoint are not allowed`);
|
|
222
|
+
}
|
|
223
|
+
const executablePath = resolveManifestRelative(cwd, entrypoint, `MCP "${entry.name}": stdio launcher entrypoint`);
|
|
224
|
+
if (!pathIsWithin(root, executablePath)) {
|
|
225
|
+
fail(`MCP "${entry.name}": stdio script escapes plugin root: ${entrypoint}`);
|
|
226
|
+
}
|
|
227
|
+
const extension = path.extname(executablePath).toLowerCase();
|
|
228
|
+
const allowedExtensions = command === "node" ? new Set([".mjs"]) : new Set([".mjs", ".ts", ".jsx", ".tsx"]);
|
|
229
|
+
if (!allowedExtensions.has(extension)) {
|
|
230
|
+
fail(`MCP "${entry.name}": unsupported ${command} entrypoint extension: ${extension || "<none>"}`);
|
|
231
|
+
}
|
|
232
|
+
const ownedRelativePaths = [path.relative(root, executablePath)];
|
|
233
|
+
for (const arg of args.slice(1)) {
|
|
234
|
+
if (arg.startsWith("-") || !isFileLikeArgument(arg)) continue;
|
|
235
|
+
const resolvedArg = resolveManifestRelative(cwd, arg, `MCP "${entry.name}": stdio arg`);
|
|
236
|
+
if (!pathIsWithin(root, resolvedArg)) fail(`MCP "${entry.name}": stdio arg escapes plugin root: ${arg}`);
|
|
237
|
+
ownedRelativePaths.push(path.relative(root, resolvedArg));
|
|
238
|
+
}
|
|
239
|
+
return {
|
|
240
|
+
kind: "launcher",
|
|
241
|
+
launcher: command as "node" | "bun",
|
|
242
|
+
entrypoint,
|
|
243
|
+
executablePath,
|
|
244
|
+
ownedRelativePath: ownedRelativePaths[0] as string,
|
|
245
|
+
ownedRelativePaths,
|
|
246
|
+
cwd,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/** stdio launcher/path confinement policy. */
|
|
251
|
+
export function assertStdioAllowed(entry: GjcPluginMcpManifestEntry, ctx: StdioPolicyContext): void {
|
|
252
|
+
classifyStdioInvocation(entry, ctx);
|
|
224
253
|
}
|
|
225
254
|
|
|
226
255
|
/**
|
|
@@ -11,6 +11,19 @@ export function gjcPluginProjectRoot(cwd: string): string {
|
|
|
11
11
|
return path.join(cwd, ".gjc", "gjc-plugins");
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
export function gjcPluginSafeDirectoryName(name: string): string {
|
|
15
|
+
const segment = name.replace(/[^a-zA-Z0-9._-]/g, "-").replace(/^-+|-+$/g, "");
|
|
16
|
+
if (!segment || segment === "." || segment === "..") {
|
|
17
|
+
throw new GjcPluginLoadError("invalid_manifest", `GJC plugin name is not a safe directory segment: ${name}`);
|
|
18
|
+
}
|
|
19
|
+
return segment;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function gjcPluginInstallRoot(scope: "user" | "project", cwd: string, name: string): string {
|
|
23
|
+
const root = scope === "user" ? gjcPluginUserRoot() : gjcPluginProjectRoot(cwd);
|
|
24
|
+
return path.join(root, gjcPluginSafeDirectoryName(name));
|
|
25
|
+
}
|
|
26
|
+
|
|
14
27
|
function isEnoent(error: unknown): boolean {
|
|
15
28
|
return (error as NodeJS.ErrnoException).code === "ENOENT";
|
|
16
29
|
}
|