@gajae-code/coding-agent 0.16.7 → 0.17.1
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 +180 -1
- package/dist/types/capability/fs.d.ts +37 -4
- package/dist/types/capability/index.d.ts +19 -0
- package/dist/types/capability/types.d.ts +9 -0
- package/dist/types/cli/doctor/args.d.ts +36 -0
- package/dist/types/cli/doctor/checks.d.ts +18 -0
- package/dist/types/cli/doctor/config-repairs.d.ts +38 -0
- package/dist/types/cli/doctor/context.d.ts +89 -0
- package/dist/types/cli/doctor/files.d.ts +27 -0
- package/dist/types/cli/doctor/ids.d.ts +20 -0
- package/dist/types/cli/doctor/install-repairs.d.ts +94 -0
- package/dist/types/cli/doctor/journal.d.ts +43 -0
- package/dist/types/cli/doctor/managed-link.d.ts +39 -0
- package/dist/types/cli/doctor/native-probe.d.ts +2 -0
- package/dist/types/cli/doctor/permission-repairs.d.ts +25 -0
- package/dist/types/cli/doctor/plugin-quarantine.d.ts +77 -0
- package/dist/types/cli/doctor/plugin-restore.d.ts +40 -0
- package/dist/types/cli/doctor/plugin-targets.d.ts +11 -0
- package/dist/types/cli/doctor/probe-client.d.ts +9 -0
- package/dist/types/cli/doctor/probe-types.d.ts +18 -0
- package/dist/types/cli/doctor/probe.d.ts +3 -0
- package/dist/types/cli/doctor/projection-probe.d.ts +2 -0
- package/dist/types/cli/doctor/repairs.d.ts +28 -0
- package/dist/types/cli/doctor/report.d.ts +27 -0
- package/dist/types/cli/doctor/runner.d.ts +4 -0
- package/dist/types/cli/doctor/safety.d.ts +10 -0
- package/dist/types/cli/doctor/service-repairs.d.ts +8 -0
- package/dist/types/cli/doctor/service-targets.d.ts +41 -0
- package/dist/types/cli/doctor/types.d.ts +145 -0
- package/dist/types/cli/doctor-cli.d.ts +7 -0
- package/dist/types/cli/doctor-supervisor.d.ts +121 -0
- package/dist/types/cli/doctor-worker.d.ts +29 -0
- package/dist/types/cli/install-activation.d.ts +158 -0
- package/dist/types/cli/macos-community-app.d.ts +41 -0
- package/dist/types/cli/mcp-cli.d.ts +0 -11
- package/dist/types/cli/update-cli.d.ts +41 -4
- package/dist/types/cli-main.d.ts +174 -0
- package/dist/types/cli.d.ts +1 -171
- package/dist/types/commands/doctor.d.ts +7 -0
- package/dist/types/commands/sdk.d.ts +17 -8
- package/dist/types/config/autorouting-tier-map.d.ts +19 -0
- package/dist/types/config/file-lock.d.ts +27 -3
- package/dist/types/config/model-preset-registry.d.ts +1 -0
- package/dist/types/config/model-registry.d.ts +12 -5
- package/dist/types/config/model-resolver.d.ts +16 -3
- package/dist/types/config/models-config-schema.d.ts +2 -0
- package/dist/types/config/settings-schema.d.ts +1 -1
- package/dist/types/coordinator-mcp/question-gate-codec.d.ts +1 -1
- package/dist/types/coordinator-mcp/session-reaper.d.ts +15 -5
- package/dist/types/cursor.d.ts +9 -9
- package/dist/types/discovery/agents-md.d.ts +6 -1
- package/dist/types/discovery/helpers.d.ts +36 -7
- package/dist/types/discovery/index.d.ts +1 -1
- package/dist/types/discovery/mcp-json.d.ts +2 -0
- package/dist/types/extensibility/extensions/loader.d.ts +22 -1
- package/dist/types/extensibility/gjc-plugins/lifecycle.d.ts +14 -1
- package/dist/types/extensibility/gjc-plugins/paths.d.ts +2 -1
- package/dist/types/extensibility/gjc-plugins/types.d.ts +25 -0
- package/dist/types/extensibility/plugins/manager.d.ts +33 -4
- package/dist/types/extensibility/plugins/marketplace/cache.d.ts +6 -0
- package/dist/types/extensibility/plugins/marketplace/manager.d.ts +186 -0
- package/dist/types/extensibility/plugins/marketplace/registry.d.ts +27 -0
- package/dist/types/extensibility/plugins/marketplace/source-resolver.d.ts +16 -1
- package/dist/types/extensibility/runtime-skill-discovery.d.ts +16 -3
- package/dist/types/gjc-runtime/autoresearch-runtime.d.ts +6 -0
- package/dist/types/gjc-runtime/launch-worktree.d.ts +53 -0
- package/dist/types/gjc-runtime/session-layout.d.ts +8 -0
- package/dist/types/gjc-runtime/session-state-lock.d.ts +15 -0
- package/dist/types/gjc-runtime/session-state-sidecar.d.ts +13 -0
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +6 -0
- package/dist/types/main.d.ts +19 -1
- package/dist/types/modes/acp/acp-agent.d.ts +40 -0
- package/dist/types/modes/components/agent-dashboard.d.ts +1 -0
- package/dist/types/modes/components/model-selector.d.ts +2 -0
- package/dist/types/modes/interactive-mode.d.ts +1 -1
- package/dist/types/runtime-mcp/config-writer.d.ts +47 -0
- package/dist/types/runtime-mcp/policy-json-edit.d.ts +60 -0
- package/dist/types/runtime-mcp/startup-policy.d.ts +4 -0
- package/dist/types/runtime-mcp/types.d.ts +2 -2
- package/dist/types/sdk/acp/adapter.d.ts +5 -1
- package/dist/types/sdk/broker/broker.d.ts +51 -0
- package/dist/types/sdk/broker/daemon-entry.d.ts +39 -0
- package/dist/types/sdk/broker/discovery.d.ts +38 -0
- package/dist/types/sdk/broker/doctor-restart.d.ts +79 -0
- package/dist/types/sdk/broker/endpoint-authority.d.ts +7 -0
- package/dist/types/sdk/broker/ensure.d.ts +14 -0
- package/dist/types/sdk/broker/lifecycle.d.ts +2 -0
- package/dist/types/sdk/broker/process-incarnation.d.ts +50 -0
- package/dist/types/sdk/broker/runtime.d.ts +26 -0
- package/dist/types/sdk/broker/session-index.d.ts +13 -4
- package/dist/types/sdk/broker/worktree-occupancy.d.ts +14 -0
- package/dist/types/sdk/bus/chat-daemon-cli.d.ts +16 -0
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +101 -6
- package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +16 -0
- package/dist/types/sdk/bus/daemon-startup-exclusion.d.ts +43 -0
- package/dist/types/sdk/bus/doctor-daemon-restart-client.d.ts +51 -0
- package/dist/types/sdk/bus/doctor-daemon-restart.d.ts +39 -0
- package/dist/types/sdk/bus/index.d.ts +2 -0
- package/dist/types/sdk/bus/notification-service.d.ts +3 -0
- package/dist/types/sdk/bus/telegram-daemon-cli.d.ts +11 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +1 -1
- package/dist/types/sdk/bus/telegram-daemon-control.d.ts +5 -0
- package/dist/types/sdk/bus/telegram-daemon-owner-registry.d.ts +1 -0
- package/dist/types/sdk/bus/telegram-daemon.d.ts +36 -5
- package/dist/types/sdk/cli/session-cli.d.ts +1 -0
- package/dist/types/sdk/host/session-runtime.d.ts +4 -0
- package/dist/types/sdk/host/surface-policy.d.ts +3 -1
- package/dist/types/sdk/lifecycle/service.d.ts +44 -10
- package/dist/types/sdk/prompt-deadline-lease.d.ts +6 -3
- package/dist/types/sdk/prompt-deadline-manager.d.ts +2 -2
- package/dist/types/sdk/prompt-failure.d.ts +47 -0
- package/dist/types/sdk/prompt-status.d.ts +19 -0
- package/dist/types/sdk/router/session-router.d.ts +3 -4
- package/dist/types/sdk/service-artifact-paths.d.ts +16 -0
- package/dist/types/sdk/session-authority.d.ts +9 -0
- package/dist/types/sdk/session.d.ts +3 -1
- package/dist/types/session/agent-session.d.ts +1 -1
- package/dist/types/session/blob-store.d.ts +1 -1
- package/dist/types/session/fallback-chain-controller.d.ts +3 -6
- package/dist/types/session/internal/managed-session-scope.d.ts +44 -0
- package/dist/types/session/primary-control-surface.d.ts +4 -0
- package/dist/types/session/session-manager.d.ts +6 -0
- package/dist/types/system-prompt.d.ts +6 -0
- package/dist/types/tools/ask.d.ts +25 -0
- package/dist/types/tools/image-gen.d.ts +0 -4
- package/dist/types/tools/skill-discovery.d.ts +7 -5
- package/dist/types/tools/ultragoal-ask-guard.d.ts +7 -4
- package/dist/types/utils/changelog.d.ts +0 -9
- package/dist/types/utils/mupdf-wasm.d.ts +1 -0
- package/package.json +9 -8
- package/scripts/compile-args.ts +8 -4
- package/src/capability/fs.ts +395 -17
- package/src/capability/index.ts +273 -10
- package/src/capability/types.ts +9 -0
- package/src/cli/customize-doctor.ts +18 -12
- package/src/cli/doctor/args.ts +236 -0
- package/src/cli/doctor/checks.ts +431 -0
- package/src/cli/doctor/config-repairs.ts +517 -0
- package/src/cli/doctor/context.ts +149 -0
- package/src/cli/doctor/files.ts +149 -0
- package/src/cli/doctor/ids.ts +115 -0
- package/src/cli/doctor/install-repairs.ts +335 -0
- package/src/cli/doctor/journal.ts +423 -0
- package/src/cli/doctor/managed-link.ts +514 -0
- package/src/cli/doctor/native-probe.ts +13 -0
- package/src/cli/doctor/permission-repairs.ts +242 -0
- package/src/cli/doctor/plugin-quarantine.ts +377 -0
- package/src/cli/doctor/plugin-restore.ts +59 -0
- package/src/cli/doctor/plugin-targets.ts +373 -0
- package/src/cli/doctor/probe-client.ts +195 -0
- package/src/cli/doctor/probe-types.ts +21 -0
- package/src/cli/doctor/probe.ts +42 -0
- package/src/cli/doctor/projection-probe.ts +249 -0
- package/src/cli/doctor/repairs.ts +1157 -0
- package/src/cli/doctor/report.ts +176 -0
- package/src/cli/doctor/runner.ts +342 -0
- package/src/cli/doctor/safety.ts +40 -0
- package/src/cli/doctor/service-repairs.ts +452 -0
- package/src/cli/doctor/service-targets.ts +274 -0
- package/src/cli/doctor/types.ts +164 -0
- package/src/cli/doctor-cli.ts +62 -0
- package/src/cli/doctor-supervisor.ts +571 -0
- package/src/cli/doctor-worker.ts +181 -0
- package/src/cli/install-activation.ts +666 -0
- package/src/cli/macos-community-app.ts +1449 -0
- package/src/cli/mcp-cli.ts +11 -21
- package/src/cli/nofile-limit.ts +5 -1
- package/src/cli/plugin-cli.ts +6 -1
- package/src/cli/update-cli.ts +362 -264
- package/src/cli-main.ts +517 -0
- package/src/cli.ts +64 -433
- package/src/commands/autoresearch.ts +11 -5
- package/src/commands/completion.ts +1 -1
- package/src/commands/doctor.ts +13 -0
- package/src/commands/sdk.ts +58 -10
- package/src/commands/ultragoal.ts +11 -5
- package/src/config/autorouting-tier-map.ts +7 -0
- package/src/config/file-lock.ts +736 -71
- package/src/config/mcp-schema.json +3 -3
- package/src/config/model-preset-registry.ts +1 -0
- package/src/config/model-registry.ts +80 -27
- package/src/config/model-resolver.ts +33 -4
- package/src/config/models-config-schema.ts +2 -0
- package/src/config/settings-schema.ts +6 -2
- package/src/coordinator-mcp/question-gate-codec.ts +1 -0
- package/src/coordinator-mcp/server.ts +534 -51
- package/src/coordinator-mcp/session-reaper.ts +64 -8
- package/src/cursor.ts +223 -53
- package/src/discovery/agents-md.ts +74 -8
- package/src/discovery/agents.ts +32 -7
- package/src/discovery/builtin.ts +184 -75
- package/src/discovery/claude-plugins.ts +85 -17
- package/src/discovery/cline.ts +38 -10
- package/src/discovery/cursor.ts +19 -6
- package/src/discovery/gemini.ts +62 -22
- package/src/discovery/github.ts +13 -3
- package/src/discovery/helpers.ts +483 -89
- package/src/discovery/index.ts +1 -0
- package/src/discovery/mcp-json.ts +36 -10
- package/src/discovery/opencode.ts +36 -19
- package/src/discovery/ssh.ts +11 -8
- package/src/discovery/windsurf.ts +12 -3
- package/src/exec/bash-executor.ts +10 -3
- package/src/exec/isolated-shell.ts +15 -2
- package/src/extensibility/extensions/loader.ts +88 -26
- package/src/extensibility/gjc-plugins/lifecycle.ts +189 -0
- package/src/extensibility/gjc-plugins/paths.ts +4 -1
- package/src/extensibility/gjc-plugins/types.ts +27 -0
- package/src/extensibility/plugins/manager.ts +200 -22
- package/src/extensibility/plugins/marketplace/cache.ts +55 -2
- package/src/extensibility/plugins/marketplace/manager.ts +1262 -162
- package/src/extensibility/plugins/marketplace/registry.ts +153 -0
- package/src/extensibility/plugins/marketplace/source-resolver.ts +116 -10
- package/src/extensibility/runtime-skill-discovery.ts +61 -9
- package/src/extensibility/skill-management.ts +7 -1
- package/src/gjc-runtime/autoresearch-runtime.ts +10 -1
- package/src/gjc-runtime/launch-worktree.test.ts +248 -0
- package/src/gjc-runtime/launch-worktree.ts +275 -38
- package/src/gjc-runtime/repository-binding.ts +26 -1
- package/src/gjc-runtime/session-layout.ts +10 -0
- package/src/gjc-runtime/session-state-lock.ts +330 -23
- package/src/gjc-runtime/session-state-sidecar.ts +328 -80
- package/src/gjc-runtime/ultragoal-runtime.ts +10 -1
- package/src/harness-control-plane/session-lease.ts +2 -2
- package/src/internal-urls/docs-index.generated.ts +28 -26
- package/src/main.ts +150 -29
- package/src/memories/index.ts +24 -2
- package/src/modes/acp/acp-agent.ts +522 -68
- package/src/modes/components/agent-dashboard.ts +3 -1
- package/src/modes/components/model-selector.ts +28 -19
- package/src/modes/components/plugin-settings.ts +2 -1
- package/src/modes/controllers/selector-controller.ts +15 -9
- package/src/modes/interactive-mode.ts +21 -3
- package/src/prompts/system/system-prompt.md +5 -1
- package/src/prompts/tools/browser.md +1 -1
- package/src/prompts/tools/move-session.md +4 -0
- package/src/prompts/tools/read.md +2 -1
- package/src/prompts/tools/skill-discovery.md +6 -5
- package/src/prompts/tools/task.md +1 -0
- package/src/runtime-mcp/config-writer.ts +228 -0
- package/src/runtime-mcp/oauth-discovery.ts +114 -14
- package/src/runtime-mcp/policy-json-edit.ts +129 -0
- package/src/runtime-mcp/startup-policy.ts +14 -0
- package/src/runtime-mcp/types.ts +2 -2
- package/src/sdk/acp/adapter.ts +27 -12
- package/src/sdk/broker/broker.ts +273 -44
- package/src/sdk/broker/daemon-entry.ts +119 -0
- package/src/sdk/broker/discovery.ts +173 -20
- package/src/sdk/broker/doctor-restart.ts +206 -0
- package/src/sdk/broker/endpoint-authority.ts +36 -0
- package/src/sdk/broker/ensure.ts +49 -14
- package/src/sdk/broker/lifecycle.ts +174 -42
- package/src/sdk/broker/process-incarnation.ts +86 -2
- package/src/sdk/broker/runtime.ts +145 -21
- package/src/sdk/broker/session-index.ts +136 -22
- package/src/sdk/broker/spawn-substrate.ts +4 -1
- package/src/sdk/broker/transport.ts +5 -0
- package/src/sdk/broker/worktree-occupancy.ts +21 -1
- package/src/sdk/bus/chat-daemon-cli.ts +63 -0
- package/src/sdk/bus/chat-daemon-control.ts +260 -64
- package/src/sdk/bus/chat-daemon-runtime.ts +141 -25
- package/src/sdk/bus/daemon-startup-exclusion.ts +119 -0
- package/src/sdk/bus/doctor-daemon-restart-client.ts +291 -0
- package/src/sdk/bus/doctor-daemon-restart.ts +92 -0
- package/src/sdk/bus/index.ts +252 -51
- package/src/sdk/bus/kind-aware-reconciliation.ts +76 -41
- package/src/sdk/bus/notification-service.ts +21 -3
- package/src/sdk/bus/reconciliation-store.ts +17 -11
- package/src/sdk/bus/telegram-daemon-cli.ts +91 -5
- package/src/sdk/bus/telegram-daemon-contract.ts +1 -1
- package/src/sdk/bus/telegram-daemon-control.ts +47 -0
- package/src/sdk/bus/telegram-daemon-owner-registry.ts +1 -1
- package/src/sdk/bus/telegram-daemon.ts +178 -13
- package/src/sdk/cli/session-cli.ts +100 -12
- package/src/sdk/host/host.ts +2 -7
- package/src/sdk/host/session-runtime.test.ts +329 -8
- package/src/sdk/host/session-runtime.ts +202 -50
- package/src/sdk/host/surface-policy.ts +8 -1
- package/src/sdk/lifecycle/service.ts +199 -22
- package/src/sdk/mcp/server.ts +1 -1
- package/src/sdk/prompt-deadline-lease.ts +12 -4
- package/src/sdk/prompt-deadline-manager.ts +5 -7
- package/src/sdk/prompt-failure.ts +148 -0
- package/src/sdk/prompt-status.ts +30 -1
- package/src/sdk/prompt-watchdog.ts +11 -3
- package/src/sdk/protocol/operation-inventory.generated.json +18 -0
- package/src/sdk/protocol/operation-registry.ts +20 -8
- package/src/sdk/router/session-router.ts +8 -3
- package/src/sdk/service-artifact-paths.ts +26 -0
- package/src/sdk/session-authority.ts +10 -0
- package/src/sdk/session.ts +361 -194
- package/src/session/agent-session.ts +398 -93
- package/src/session/blob-store.ts +9 -9
- package/src/session/fallback-chain-controller.ts +3 -7
- package/src/session/internal/managed-session-scope.ts +445 -29
- package/src/session/internal/managed-session-storage.ts +38 -6
- package/src/session/primary-control-surface.ts +12 -0
- package/src/session/session-manager.ts +11 -3
- package/src/session/session-storage.ts +1 -1
- package/src/session-import/codex.ts +6 -1
- package/src/session-import/redact.ts +7 -0
- package/src/skill-state/workflow-mutation-guard.ts +645 -39
- package/src/slash-commands/builtin-registry.ts +7 -3
- package/src/system-prompt.ts +8 -0
- package/src/task/executor.ts +36 -3
- package/src/task/types.ts +27 -5
- package/src/tools/ask.ts +114 -34
- package/src/tools/browser/actions.ts +2 -2
- package/src/tools/browser/tab-worker.ts +11 -8
- package/src/tools/descriptors.ts +6 -1
- package/src/tools/fetch.ts +7 -2
- package/src/tools/image-gen.ts +33 -34
- package/src/tools/read.ts +78 -32
- package/src/tools/skill-discovery.ts +17 -7
- package/src/tools/tool-catalog.generated.ts +8 -8
- package/src/tools/ultragoal-ask-guard.ts +16 -26
- package/src/utils/changelog.ts +7 -1
- package/src/utils/git.ts +3 -1
- package/src/utils/markit.ts +24 -2
- package/src/utils/mupdf-wasm.ts +26 -0
- package/src/web/search/providers/openai-compatible.ts +191 -14
|
@@ -5,12 +5,14 @@
|
|
|
5
5
|
* This handles AGENTS.md files that live in project root (not in config directories
|
|
6
6
|
* like .OpenAI code backend/ or .gemini/, which are handled by their respective providers).
|
|
7
7
|
*/
|
|
8
|
+
import type * as fsSync from "node:fs";
|
|
8
9
|
import * as fs from "node:fs/promises";
|
|
9
10
|
import * as path from "node:path";
|
|
10
11
|
import { registerProvider } from "../capability";
|
|
11
12
|
import { type ContextFile, contextFileCapability } from "../capability/context-file";
|
|
13
|
+
import type { FileIdentity } from "../capability/fs";
|
|
12
14
|
import type { LoadContext, LoadResult } from "../capability/types";
|
|
13
|
-
import { calculateDepth, createSourceMeta } from "./helpers";
|
|
15
|
+
import { calculateDepth, canonicalizePathWithinHome, createSourceMeta } from "./helpers";
|
|
14
16
|
|
|
15
17
|
const PROVIDER_ID = "agents-md";
|
|
16
18
|
const DISPLAY_NAME = "AGENTS.md";
|
|
@@ -25,17 +27,60 @@ const AGGREGATE_LIMIT_WARNING = "Skipped one or more AGENTS.md files that exceed
|
|
|
25
27
|
export type AgentsMdReader = (
|
|
26
28
|
filePath: string,
|
|
27
29
|
maxBytes: number,
|
|
30
|
+
options?: { noFollow?: boolean; home?: string; homeIdentity?: FileIdentity },
|
|
28
31
|
) => Promise<{ content: string | null; byteLength: number; tooLarge: boolean }>;
|
|
29
32
|
|
|
33
|
+
function sameFileIdentity(left: fsSync.Stats, right: fsSync.Stats): boolean {
|
|
34
|
+
return left.dev === right.dev && left.ino === right.ino;
|
|
35
|
+
}
|
|
36
|
+
|
|
30
37
|
async function readBoundedAgentsMdFile(
|
|
31
38
|
filePath: string,
|
|
32
39
|
maxBytes: number,
|
|
40
|
+
options?: { noFollow?: boolean; home?: string; homeIdentity?: FileIdentity },
|
|
33
41
|
): Promise<{ content: string | null; byteLength: number; tooLarge: boolean }> {
|
|
42
|
+
const noFollow = options?.noFollow === true;
|
|
43
|
+
const homeIsStable = async (): Promise<boolean> => {
|
|
44
|
+
if (!options?.home || !options.homeIdentity) return true;
|
|
45
|
+
try {
|
|
46
|
+
const current = await fs.stat(options.home);
|
|
47
|
+
return current.dev === options.homeIdentity.dev && current.ino === options.homeIdentity.ino;
|
|
48
|
+
} catch {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
let before: fsSync.Stats | undefined;
|
|
53
|
+
let canonicalPath: string | undefined;
|
|
34
54
|
try {
|
|
35
|
-
|
|
55
|
+
if (!(await homeIsStable())) return { content: null, byteLength: 0, tooLarge: false };
|
|
56
|
+
if (noFollow) {
|
|
57
|
+
// `loadAgentsMd` canonicalizes the candidate before calling the reader,
|
|
58
|
+
// but that pathname can be swapped before open. Recheck the canonical
|
|
59
|
+
// target immediately before opening and bracket the descriptor with
|
|
60
|
+
// identity checks so explicit-home reads cannot follow a raced link.
|
|
61
|
+
canonicalPath = await fs.realpath(filePath);
|
|
62
|
+
if (canonicalPath !== path.resolve(filePath)) return { content: null, byteLength: 0, tooLarge: false };
|
|
63
|
+
before = await fs.lstat(filePath);
|
|
64
|
+
if (before.isSymbolicLink() || !before.isFile() || before.nlink !== 1)
|
|
65
|
+
return { content: null, byteLength: 0, tooLarge: false };
|
|
66
|
+
}
|
|
67
|
+
const flags =
|
|
68
|
+
fs.constants.O_RDONLY |
|
|
69
|
+
(typeof fs.constants.O_NONBLOCK === "number" ? fs.constants.O_NONBLOCK : 0) |
|
|
70
|
+
(noFollow && typeof fs.constants.O_NOFOLLOW === "number" ? fs.constants.O_NOFOLLOW : 0);
|
|
71
|
+
const file = await fs.open(filePath, flags);
|
|
36
72
|
try {
|
|
37
73
|
const stats = await file.stat();
|
|
38
74
|
if (!stats.isFile()) return { content: null, byteLength: 0, tooLarge: false };
|
|
75
|
+
if (before && (!sameFileIdentity(before, stats) || stats.nlink !== 1))
|
|
76
|
+
return { content: null, byteLength: 0, tooLarge: false };
|
|
77
|
+
if (before) {
|
|
78
|
+
if (canonicalPath !== (await fs.realpath(filePath)))
|
|
79
|
+
return { content: null, byteLength: 0, tooLarge: false };
|
|
80
|
+
const after = await fs.lstat(filePath);
|
|
81
|
+
if (after.isSymbolicLink() || after.nlink !== 1 || !sameFileIdentity(before, after))
|
|
82
|
+
return { content: null, byteLength: 0, tooLarge: false };
|
|
83
|
+
}
|
|
39
84
|
const bytes = Buffer.alloc(maxBytes + 1);
|
|
40
85
|
let bytesRead = 0;
|
|
41
86
|
while (bytesRead < bytes.length) {
|
|
@@ -44,6 +89,9 @@ async function readBoundedAgentsMdFile(
|
|
|
44
89
|
bytesRead += result.bytesRead;
|
|
45
90
|
}
|
|
46
91
|
if (bytesRead > maxBytes) return { content: null, byteLength: bytesRead, tooLarge: true };
|
|
92
|
+
if (before && canonicalPath !== (await fs.realpath(filePath)))
|
|
93
|
+
return { content: null, byteLength: 0, tooLarge: false };
|
|
94
|
+
if (!(await homeIsStable())) return { content: null, byteLength: 0, tooLarge: false };
|
|
47
95
|
return {
|
|
48
96
|
content: new TextDecoder().decode(bytes.subarray(0, bytesRead)),
|
|
49
97
|
byteLength: bytesRead,
|
|
@@ -71,6 +119,17 @@ export async function loadAgentsMd(
|
|
|
71
119
|
let aggregateBytes = 0;
|
|
72
120
|
let omittedOversizedFile = false;
|
|
73
121
|
let omittedAggregateFile = false;
|
|
122
|
+
const homeRelative = path.relative(ctx.home, ctx.cwd);
|
|
123
|
+
const cwdIsWithinHome =
|
|
124
|
+
homeRelative === "" ||
|
|
125
|
+
(homeRelative !== ".." && !homeRelative.startsWith(`..${path.sep}`) && !path.isAbsolute(homeRelative));
|
|
126
|
+
const stopDirectory = ctx.repoRoot ?? (ctx.isolatedHome || cwdIsWithinHome ? ctx.home : path.parse(ctx.cwd).root);
|
|
127
|
+
const relativeStop = path.relative(stopDirectory, ctx.cwd);
|
|
128
|
+
const effectiveStopDirectory =
|
|
129
|
+
relativeStop === "" ||
|
|
130
|
+
(relativeStop !== ".." && !relativeStop.startsWith(`..${path.sep}`) && !path.isAbsolute(relativeStop))
|
|
131
|
+
? stopDirectory
|
|
132
|
+
: ctx.cwd;
|
|
74
133
|
|
|
75
134
|
while (true) {
|
|
76
135
|
scannedDirectories += 1;
|
|
@@ -81,25 +140,32 @@ export async function loadAgentsMd(
|
|
|
81
140
|
if (!baseName.startsWith(".")) {
|
|
82
141
|
const remainingAggregateBytes = MAX_AGGREGATE_BYTES - aggregateBytes;
|
|
83
142
|
const allowedBytes = Math.min(MAX_FILE_BYTES, remainingAggregateBytes);
|
|
84
|
-
const
|
|
143
|
+
const authorizedCandidate = await canonicalizePathWithinHome(ctx, candidate, undefined, "project");
|
|
144
|
+
const result = authorizedCandidate
|
|
145
|
+
? await readCandidate(authorizedCandidate, allowedBytes, {
|
|
146
|
+
noFollow: ctx.isolatedHome === true,
|
|
147
|
+
home: ctx.home,
|
|
148
|
+
homeIdentity: ctx.homeIdentity,
|
|
149
|
+
})
|
|
150
|
+
: { content: null, byteLength: 0, tooLarge: false };
|
|
85
151
|
if (result.tooLarge) {
|
|
86
152
|
if (allowedBytes < MAX_FILE_BYTES) omittedAggregateFile = true;
|
|
87
153
|
else omittedOversizedFile = true;
|
|
88
154
|
} else if (result.content !== null) {
|
|
89
|
-
const
|
|
155
|
+
const filePath = authorizedCandidate ?? candidate;
|
|
156
|
+
const fileDir = path.dirname(filePath);
|
|
90
157
|
items.push({
|
|
91
|
-
path:
|
|
158
|
+
path: filePath,
|
|
92
159
|
content: result.content,
|
|
93
160
|
level: "project",
|
|
94
161
|
depth: calculateDepth(ctx.cwd, fileDir, path.sep),
|
|
95
|
-
_source: createSourceMeta(PROVIDER_ID,
|
|
162
|
+
_source: createSourceMeta(PROVIDER_ID, filePath, "project"),
|
|
96
163
|
});
|
|
97
164
|
aggregateBytes += result.byteLength;
|
|
98
165
|
}
|
|
99
166
|
}
|
|
100
167
|
|
|
101
|
-
|
|
102
|
-
if (current === stopDirectory) break;
|
|
168
|
+
if (current === effectiveStopDirectory) break;
|
|
103
169
|
if (scannedDirectories === MAX_ANCESTOR_DIRECTORIES) {
|
|
104
170
|
warnings.push(DIRECTORY_LIMIT_WARNING);
|
|
105
171
|
break;
|
package/src/discovery/agents.ts
CHANGED
|
@@ -18,7 +18,9 @@ import type { LoadContext, LoadResult } from "../capability/types";
|
|
|
18
18
|
import {
|
|
19
19
|
buildRuleFromMarkdown,
|
|
20
20
|
calculateDepth,
|
|
21
|
+
canonicalizePathWithinHome,
|
|
21
22
|
createSourceMeta,
|
|
23
|
+
getReadOptions,
|
|
22
24
|
loadFilesFromDir,
|
|
23
25
|
scanSkillsFromDir,
|
|
24
26
|
} from "./helpers";
|
|
@@ -46,13 +48,24 @@ function getUserPathCandidates(ctx: LoadContext, ...segments: string[]): string[
|
|
|
46
48
|
export function getProjectPathCandidates(ctx: LoadContext, ...segments: string[]): string[] {
|
|
47
49
|
const paths: string[] = [];
|
|
48
50
|
let current = ctx.cwd;
|
|
51
|
+
const homeRelative = path.relative(ctx.home, ctx.cwd);
|
|
52
|
+
const cwdIsWithinHome =
|
|
53
|
+
homeRelative === "" ||
|
|
54
|
+
(homeRelative !== ".." && !homeRelative.startsWith(`..${path.sep}`) && !path.isAbsolute(homeRelative));
|
|
55
|
+
const stopDirectory = ctx.repoRoot ?? (ctx.isolatedHome || cwdIsWithinHome ? ctx.home : path.parse(ctx.cwd).root);
|
|
56
|
+
const relativeStop = path.relative(stopDirectory, ctx.cwd);
|
|
57
|
+
const effectiveStopDirectory =
|
|
58
|
+
relativeStop === "" ||
|
|
59
|
+
(relativeStop !== ".." && !relativeStop.startsWith(`..${path.sep}`) && !path.isAbsolute(relativeStop))
|
|
60
|
+
? stopDirectory
|
|
61
|
+
: ctx.cwd;
|
|
49
62
|
while (true) {
|
|
50
63
|
if (current !== ctx.home) {
|
|
51
64
|
for (const baseDir of AGENT_DIR_CANDIDATES) {
|
|
52
65
|
paths.push(path.join(current, baseDir, ...segments));
|
|
53
66
|
}
|
|
54
67
|
}
|
|
55
|
-
if (current ===
|
|
68
|
+
if (current === effectiveStopDirectory) break;
|
|
56
69
|
const parent = path.dirname(current);
|
|
57
70
|
if (parent === current) break;
|
|
58
71
|
current = parent;
|
|
@@ -181,12 +194,21 @@ registerProvider<SlashCommand>(slashCommandCapability.id, {
|
|
|
181
194
|
// Context Files (AGENTS.md)
|
|
182
195
|
async function loadContextFiles(ctx: LoadContext): Promise<LoadResult<ContextFile>> {
|
|
183
196
|
const load = async (filePath: string, level: "user" | "project"): Promise<ContextFile | null> => {
|
|
184
|
-
const
|
|
197
|
+
const scope = level === "user" ? "user" : "project";
|
|
198
|
+
const canonicalPath = await canonicalizePathWithinHome(ctx, filePath, undefined, scope);
|
|
199
|
+
if (!canonicalPath) return null;
|
|
200
|
+
const content = await readFile(canonicalPath, getReadOptions(ctx, scope));
|
|
185
201
|
if (!content) return null;
|
|
186
|
-
//
|
|
187
|
-
const ancestorDir = path.dirname(path.dirname(
|
|
202
|
+
// canonicalPath is <ancestor>/.agent(s)/AGENTS.md — go up past the config dir to the ancestor
|
|
203
|
+
const ancestorDir = path.dirname(path.dirname(canonicalPath));
|
|
188
204
|
const depth = level === "project" ? calculateDepth(ctx.cwd, ancestorDir, path.sep) : undefined;
|
|
189
|
-
return {
|
|
205
|
+
return {
|
|
206
|
+
path: canonicalPath,
|
|
207
|
+
content,
|
|
208
|
+
level,
|
|
209
|
+
depth,
|
|
210
|
+
_source: createSourceMeta(PROVIDER_ID, canonicalPath, level),
|
|
211
|
+
};
|
|
190
212
|
};
|
|
191
213
|
|
|
192
214
|
const results = await Promise.all([
|
|
@@ -208,9 +230,12 @@ registerProvider<ContextFile>(contextFileCapability.id, {
|
|
|
208
230
|
// System Prompt (SYSTEM.md)
|
|
209
231
|
async function loadSystemPrompt(ctx: LoadContext): Promise<LoadResult<SystemPrompt>> {
|
|
210
232
|
const load = async (filePath: string, level: "user" | "project"): Promise<SystemPrompt | null> => {
|
|
211
|
-
const
|
|
233
|
+
const scope = level === "user" ? "user" : "project";
|
|
234
|
+
const canonicalPath = await canonicalizePathWithinHome(ctx, filePath, undefined, scope);
|
|
235
|
+
if (!canonicalPath) return null;
|
|
236
|
+
const content = await readFile(canonicalPath, getReadOptions(ctx, scope));
|
|
212
237
|
if (!content) return null;
|
|
213
|
-
return { path:
|
|
238
|
+
return { path: canonicalPath, content, level, _source: createSourceMeta(PROVIDER_ID, canonicalPath, level) };
|
|
214
239
|
};
|
|
215
240
|
|
|
216
241
|
const results = await Promise.all([
|