@agent-loom/loom 1.0.1 → 1.0.3
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 +69 -0
- package/dist/acp/client.d.ts +182 -0
- package/dist/acp/client.d.ts.map +1 -0
- package/dist/acp/client.js +432 -0
- package/dist/acp/client.js.map +1 -0
- package/dist/acp/index.d.ts +5 -0
- package/dist/acp/index.d.ts.map +1 -0
- package/dist/acp/index.js +3 -0
- package/dist/acp/index.js.map +1 -0
- package/dist/acp/run.d.ts +41 -0
- package/dist/acp/run.d.ts.map +1 -0
- package/dist/acp/run.js +32 -0
- package/dist/acp/run.js.map +1 -0
- package/dist/apply.d.ts +17 -6
- package/dist/apply.d.ts.map +1 -1
- package/dist/apply.js +85 -47
- package/dist/apply.js.map +1 -1
- package/dist/chat/chat.d.ts +108 -0
- package/dist/chat/chat.d.ts.map +1 -0
- package/dist/chat/chat.js +221 -0
- package/dist/chat/chat.js.map +1 -0
- package/dist/chat/discovery.d.ts +30 -0
- package/dist/chat/discovery.d.ts.map +1 -0
- package/dist/chat/discovery.js +68 -0
- package/dist/chat/discovery.js.map +1 -0
- package/dist/chat/frontmatter.d.ts +12 -0
- package/dist/chat/frontmatter.d.ts.map +1 -0
- package/dist/chat/frontmatter.js +11 -0
- package/dist/chat/frontmatter.js.map +1 -0
- package/dist/chat/index.d.ts +16 -0
- package/dist/chat/index.d.ts.map +1 -0
- package/dist/chat/index.js +11 -0
- package/dist/chat/index.js.map +1 -0
- package/dist/chat/registry.d.ts +73 -0
- package/dist/chat/registry.d.ts.map +1 -0
- package/dist/chat/registry.js +118 -0
- package/dist/chat/registry.js.map +1 -0
- package/dist/chat/resolve-agent.d.ts +39 -0
- package/dist/chat/resolve-agent.d.ts.map +1 -0
- package/dist/chat/resolve-agent.js +36 -0
- package/dist/chat/resolve-agent.js.map +1 -0
- package/dist/chat/suggest.d.ts +20 -0
- package/dist/chat/suggest.d.ts.map +1 -0
- package/dist/chat/suggest.js +55 -0
- package/dist/chat/suggest.js.map +1 -0
- package/dist/cli.js +628 -75
- package/dist/cli.js.map +1 -1
- package/dist/clone.d.ts +21 -3
- package/dist/clone.d.ts.map +1 -1
- package/dist/clone.js +240 -12
- package/dist/clone.js.map +1 -1
- package/dist/copilot/mcp.d.ts +48 -0
- package/dist/copilot/mcp.d.ts.map +1 -0
- package/dist/copilot/mcp.js +146 -0
- package/dist/copilot/mcp.js.map +1 -0
- package/dist/copilot/resolve.d.ts +33 -0
- package/dist/copilot/resolve.d.ts.map +1 -0
- package/dist/copilot/resolve.js +96 -0
- package/dist/copilot/resolve.js.map +1 -0
- package/dist/copilot/spawn.d.ts +51 -0
- package/dist/copilot/spawn.d.ts.map +1 -0
- package/dist/copilot/spawn.js +132 -0
- package/dist/copilot/spawn.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/launch/index.d.ts +10 -0
- package/dist/launch/index.d.ts.map +1 -0
- package/dist/launch/index.js +9 -0
- package/dist/launch/index.js.map +1 -0
- package/dist/launch/stage.d.ts +62 -0
- package/dist/launch/stage.d.ts.map +1 -0
- package/dist/launch/stage.js +108 -0
- package/dist/launch/stage.js.map +1 -0
- package/dist/manifest.d.ts +165 -18
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +980 -225
- package/dist/manifest.js.map +1 -1
- package/dist/renderers/claude.d.ts +5 -0
- package/dist/renderers/claude.d.ts.map +1 -1
- package/dist/renderers/claude.js +17 -3
- package/dist/renderers/claude.js.map +1 -1
- package/dist/renderers/copilot.d.ts +1 -1
- package/dist/renderers/copilot.d.ts.map +1 -1
- package/dist/renderers/copilot.js +205 -22
- package/dist/renderers/copilot.js.map +1 -1
- package/dist/repo-clone.js +17 -11
- package/dist/repo-clone.js.map +1 -1
- package/dist/resolve-template.d.ts +12 -4
- package/dist/resolve-template.d.ts.map +1 -1
- package/dist/resolve-template.js +39 -8
- package/dist/resolve-template.js.map +1 -1
- package/dist/run/index.d.ts +4 -0
- package/dist/run/index.d.ts.map +1 -0
- package/dist/run/index.js +2 -0
- package/dist/run/index.js.map +1 -0
- package/dist/run/run.d.ts +143 -0
- package/dist/run/run.d.ts.map +1 -0
- package/dist/run/run.js +406 -0
- package/dist/run/run.js.map +1 -0
- package/dist/search-registry.d.ts +10 -3
- package/dist/search-registry.d.ts.map +1 -1
- package/dist/search-registry.js +16 -16
- package/dist/search-registry.js.map +1 -1
- package/dist/sessions/index.d.ts +16 -0
- package/dist/sessions/index.d.ts.map +1 -0
- package/dist/sessions/index.js +15 -0
- package/dist/sessions/index.js.map +1 -0
- package/dist/sessions/store.d.ts +56 -0
- package/dist/sessions/store.d.ts.map +1 -0
- package/dist/sessions/store.js +220 -0
- package/dist/sessions/store.js.map +1 -0
- package/dist/sessions/types.d.ts +62 -0
- package/dist/sessions/types.d.ts.map +1 -0
- package/dist/sessions/types.js +5 -0
- package/dist/sessions/types.js.map +1 -0
- package/dist/skill-fetcher.d.ts.map +1 -1
- package/dist/skill-fetcher.js +5 -6
- package/dist/skill-fetcher.js.map +1 -1
- package/dist/types.d.ts +123 -41
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +12 -0
- package/dist/types.js.map +1 -1
- package/dist/util/binary-cache.d.ts +53 -0
- package/dist/util/binary-cache.d.ts.map +1 -0
- package/dist/util/binary-cache.js +211 -0
- package/dist/util/binary-cache.js.map +1 -0
- package/dist/util/frontmatter.d.ts +53 -0
- package/dist/util/frontmatter.d.ts.map +1 -0
- package/dist/util/frontmatter.js +85 -0
- package/dist/util/frontmatter.js.map +1 -0
- package/dist/util/loom-home.d.ts +19 -0
- package/dist/util/loom-home.d.ts.map +1 -0
- package/dist/util/loom-home.js +37 -0
- package/dist/util/loom-home.js.map +1 -0
- package/dist/util/workspace-folder.d.ts +29 -0
- package/dist/util/workspace-folder.d.ts.map +1 -0
- package/dist/util/workspace-folder.js +43 -0
- package/dist/util/workspace-folder.js.map +1 -0
- package/dist/validate.d.ts +7 -1
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +90 -17
- package/dist/validate.js.map +1 -1
- package/package.json +31 -2
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP config discovery, composition, and materialization helpers.
|
|
3
|
+
* Shared across chat/ and run/ without duplicating logic.
|
|
4
|
+
*/
|
|
5
|
+
import { existsSync, readFileSync, mkdtempSync, rmSync } from 'node:fs';
|
|
6
|
+
import { writeFile } from 'node:fs/promises';
|
|
7
|
+
import { join } from 'node:path';
|
|
8
|
+
import { tmpdir } from 'node:os';
|
|
9
|
+
import { env } from 'node:process';
|
|
10
|
+
/**
|
|
11
|
+
* Discover an MCP configuration in the given workspace and translate it
|
|
12
|
+
* into the Copilot-CLI `mcpServers`-shaped JSON string (suitable for
|
|
13
|
+
* `--additional-mcp-config @<file>`). Returns null if no servers are
|
|
14
|
+
* usable. Also handles auth-bridge wiring for MCP servers that need a
|
|
15
|
+
* browser-acquired token in the spawn env.
|
|
16
|
+
*/
|
|
17
|
+
export function buildCopilotMcpConfigJson(cwd) {
|
|
18
|
+
return discoverMcpConfig(cwd);
|
|
19
|
+
}
|
|
20
|
+
function discoverMcpConfig(cwd) {
|
|
21
|
+
const candidates = [
|
|
22
|
+
join(cwd, '.mcp.json'),
|
|
23
|
+
join(cwd, '.vscode', 'mcp.json'),
|
|
24
|
+
join(cwd, 'mcp.json'),
|
|
25
|
+
];
|
|
26
|
+
for (const candidate of candidates) {
|
|
27
|
+
if (!existsSync(candidate))
|
|
28
|
+
continue;
|
|
29
|
+
try {
|
|
30
|
+
const raw = readFileSync(candidate, 'utf-8');
|
|
31
|
+
const parsed = JSON.parse(raw);
|
|
32
|
+
const servers = parsed.servers ?? parsed.mcpServers ?? {};
|
|
33
|
+
if (Object.keys(servers).length === 0)
|
|
34
|
+
continue;
|
|
35
|
+
const cliConfig = { mcpServers: {} };
|
|
36
|
+
for (const [name, config] of Object.entries(servers)) {
|
|
37
|
+
const entry = config;
|
|
38
|
+
const cliEntry = {};
|
|
39
|
+
// For MCP servers with browser auth, switch to token-from-cache mode
|
|
40
|
+
// so headless specialists can use them without launching browsers.
|
|
41
|
+
const entryEnv = entry.env ?? {};
|
|
42
|
+
if (entryEnv.HOWLER_AUTH_MODE === 'browser') {
|
|
43
|
+
const cachePath = join(env.HOME ?? env.USERPROFILE ?? '', '.icm_mcp_cache', 'icm_token_cache.json');
|
|
44
|
+
if (existsSync(cachePath)) {
|
|
45
|
+
try {
|
|
46
|
+
const cache = JSON.parse(readFileSync(cachePath, 'utf-8'));
|
|
47
|
+
const token = cache?.public?.icm_token;
|
|
48
|
+
if (token) {
|
|
49
|
+
cliEntry.env = { ...entryEnv, HOWLER_AUTH_MODE: 'token', HOWLER_ICM_TOKEN: token };
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (entry.type === 'stdio') {
|
|
64
|
+
cliEntry.type = 'stdio';
|
|
65
|
+
if (entry.command)
|
|
66
|
+
cliEntry.command = entry.command;
|
|
67
|
+
if (entry.args)
|
|
68
|
+
cliEntry.args = entry.args;
|
|
69
|
+
if (entry.env && !cliEntry.env)
|
|
70
|
+
cliEntry.env = entry.env;
|
|
71
|
+
}
|
|
72
|
+
else if (entry.type === 'http' || entry.type === 'sse') {
|
|
73
|
+
cliEntry.type = entry.type;
|
|
74
|
+
if (entry.url)
|
|
75
|
+
cliEntry.url = entry.url;
|
|
76
|
+
}
|
|
77
|
+
cliConfig.mcpServers[name] = cliEntry;
|
|
78
|
+
}
|
|
79
|
+
return JSON.stringify(cliConfig);
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// skip
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Compose a merged MCP config from base + extras - removes, then write it to targetPath.
|
|
89
|
+
* Returns true if anything was written (non-zero servers), false otherwise.
|
|
90
|
+
*/
|
|
91
|
+
export async function writeMcpConfig(targetPath, opts) {
|
|
92
|
+
const base = opts.baseConfig
|
|
93
|
+
? JSON.parse(opts.baseConfig)
|
|
94
|
+
: { mcpServers: {} };
|
|
95
|
+
const merged = { ...base.mcpServers };
|
|
96
|
+
for (const name of opts.removeServers ?? []) {
|
|
97
|
+
delete merged[name];
|
|
98
|
+
}
|
|
99
|
+
for (const [name, cfg] of Object.entries(opts.extras ?? {})) {
|
|
100
|
+
merged[name] = cfg;
|
|
101
|
+
}
|
|
102
|
+
if (Object.keys(merged).length === 0)
|
|
103
|
+
return false;
|
|
104
|
+
await writeFile(targetPath, JSON.stringify({ mcpServers: merged }, null, 2), 'utf-8');
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Create a temporary directory, write the merged MCP config to it, and return
|
|
109
|
+
* the path + a cleanup function. Returns null when the merged config has zero servers.
|
|
110
|
+
*
|
|
111
|
+
* On any failure during the write step (e.g. malformed `baseConfig` JSON),
|
|
112
|
+
* the temp directory is removed before re-throwing — otherwise we'd leak
|
|
113
|
+
* an empty `loom-XXXX/` under tmp every failed run.
|
|
114
|
+
*/
|
|
115
|
+
export async function materializeTempMcpConfig(opts) {
|
|
116
|
+
const dir = mkdtempSync(join(tmpdir(), opts.dirPrefix ?? 'loom-'));
|
|
117
|
+
const configPath = join(dir, 'mcp-cli.json');
|
|
118
|
+
let wrote;
|
|
119
|
+
try {
|
|
120
|
+
wrote = await writeMcpConfig(configPath, opts);
|
|
121
|
+
}
|
|
122
|
+
catch (err) {
|
|
123
|
+
try {
|
|
124
|
+
rmSync(dir, { recursive: true, force: true });
|
|
125
|
+
}
|
|
126
|
+
catch { /* ignore */ }
|
|
127
|
+
throw err;
|
|
128
|
+
}
|
|
129
|
+
if (!wrote) {
|
|
130
|
+
try {
|
|
131
|
+
rmSync(dir, { recursive: true, force: true });
|
|
132
|
+
}
|
|
133
|
+
catch { /* ignore */ }
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
return {
|
|
137
|
+
path: configPath,
|
|
138
|
+
cleanup: () => {
|
|
139
|
+
try {
|
|
140
|
+
rmSync(dir, { recursive: true, force: true });
|
|
141
|
+
}
|
|
142
|
+
catch { /* ignore */ }
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=mcp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/copilot/mcp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copilot binary and agent resolution helpers.
|
|
3
|
+
* Shared across chat/ and run/ without duplicating logic.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Resolve the path to the Copilot CLI binary.
|
|
7
|
+
*
|
|
8
|
+
* Lookup order:
|
|
9
|
+
* 1. ``COPILOT_CLI_PATH`` env var (escape hatch for any setup).
|
|
10
|
+
* 2. WinGet install location (Windows only, where most users land).
|
|
11
|
+
* 3. PATH lookup (``where.exe`` on Windows, ``command -v`` on POSIX).
|
|
12
|
+
* On Windows, when ``where.exe`` returns an npm shim (``.cmd`` /
|
|
13
|
+
* ``.ps1`` / extensionless), the function probes for the
|
|
14
|
+
* platform-packaged ``copilot.exe`` next to the shim dir before
|
|
15
|
+
* surrendering to a bare-name return. This matters because
|
|
16
|
+
* ``spawnCaptured`` needs ``shell: true`` for non-``.exe`` bins,
|
|
17
|
+
* and ``cmd.exe`` mangles quoted-arg values containing spaces
|
|
18
|
+
* (e.g. ``--agent "Loom Dogfood"`` becomes ``--agent Loom Dogfood``,
|
|
19
|
+
* yielding ``error: too many arguments``). Returning the absolute
|
|
20
|
+
* ``.exe`` directly skips the shell entirely.
|
|
21
|
+
* 4. Bare ``'copilot'`` literal.
|
|
22
|
+
*
|
|
23
|
+
* The POSIX PATH branch (N3 from PR #67) matters because ``spawnCaptured``
|
|
24
|
+
* uses ``shell: false`` on POSIX -- without an absolute path, a missing
|
|
25
|
+
* ``copilot`` produces a bare ``ENOENT`` rather than a useful diagnostic.
|
|
26
|
+
*/
|
|
27
|
+
export declare function resolveCopilotBin(): string;
|
|
28
|
+
/**
|
|
29
|
+
* Given a path to an .agent.md file, parse its frontmatter and return the
|
|
30
|
+
* agent's display name. Falls back to the filename slug if no `name:` is set.
|
|
31
|
+
*/
|
|
32
|
+
export declare function resolveAgentDisplayNameFromPath(agentFilePath: string): Promise<string>;
|
|
33
|
+
//# sourceMappingURL=resolve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/copilot/resolve.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CA6D1C;AAED;;;GAGG;AACH,wBAAsB,+BAA+B,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAI5F"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copilot binary and agent resolution helpers.
|
|
3
|
+
* Shared across chat/ and run/ without duplicating logic.
|
|
4
|
+
*/
|
|
5
|
+
import { existsSync } from 'node:fs';
|
|
6
|
+
import { join, basename, dirname } from 'node:path';
|
|
7
|
+
import { execSync } from 'node:child_process';
|
|
8
|
+
import { env } from 'node:process';
|
|
9
|
+
import { platform } from 'node:os';
|
|
10
|
+
import { parseAgentFrontmatter } from '../util/frontmatter.js';
|
|
11
|
+
/**
|
|
12
|
+
* Resolve the path to the Copilot CLI binary.
|
|
13
|
+
*
|
|
14
|
+
* Lookup order:
|
|
15
|
+
* 1. ``COPILOT_CLI_PATH`` env var (escape hatch for any setup).
|
|
16
|
+
* 2. WinGet install location (Windows only, where most users land).
|
|
17
|
+
* 3. PATH lookup (``where.exe`` on Windows, ``command -v`` on POSIX).
|
|
18
|
+
* On Windows, when ``where.exe`` returns an npm shim (``.cmd`` /
|
|
19
|
+
* ``.ps1`` / extensionless), the function probes for the
|
|
20
|
+
* platform-packaged ``copilot.exe`` next to the shim dir before
|
|
21
|
+
* surrendering to a bare-name return. This matters because
|
|
22
|
+
* ``spawnCaptured`` needs ``shell: true`` for non-``.exe`` bins,
|
|
23
|
+
* and ``cmd.exe`` mangles quoted-arg values containing spaces
|
|
24
|
+
* (e.g. ``--agent "Loom Dogfood"`` becomes ``--agent Loom Dogfood``,
|
|
25
|
+
* yielding ``error: too many arguments``). Returning the absolute
|
|
26
|
+
* ``.exe`` directly skips the shell entirely.
|
|
27
|
+
* 4. Bare ``'copilot'`` literal.
|
|
28
|
+
*
|
|
29
|
+
* The POSIX PATH branch (N3 from PR #67) matters because ``spawnCaptured``
|
|
30
|
+
* uses ``shell: false`` on POSIX -- without an absolute path, a missing
|
|
31
|
+
* ``copilot`` produces a bare ``ENOENT`` rather than a useful diagnostic.
|
|
32
|
+
*/
|
|
33
|
+
export function resolveCopilotBin() {
|
|
34
|
+
if (env.COPILOT_CLI_PATH)
|
|
35
|
+
return env.COPILOT_CLI_PATH;
|
|
36
|
+
const isWindows = platform() === 'win32';
|
|
37
|
+
if (isWindows) {
|
|
38
|
+
const wingetPath = join(env.LOCALAPPDATA ?? '', 'Microsoft', 'WinGet', 'Links', 'copilot.exe');
|
|
39
|
+
if (existsSync(wingetPath))
|
|
40
|
+
return wingetPath;
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
if (isWindows) {
|
|
44
|
+
const candidates = execSync('where.exe copilot 2>nul', { encoding: 'utf-8' })
|
|
45
|
+
.split('\n')
|
|
46
|
+
.map((l) => l.trim())
|
|
47
|
+
.filter((l) => l.length > 0 && !l.includes('globalStorage'));
|
|
48
|
+
// Prefer an absolute .exe directly on PATH (e.g. WinGet link
|
|
49
|
+
// promoted earlier in the user's %PATH%).
|
|
50
|
+
const directExe = candidates.find((l) => l.toLowerCase().endsWith('.exe'));
|
|
51
|
+
if (directExe)
|
|
52
|
+
return directExe;
|
|
53
|
+
// npm-installed copilot lays out as:
|
|
54
|
+
// <npm-prefix>\copilot (extensionless POSIX-style shim)
|
|
55
|
+
// <npm-prefix>\copilot.cmd (Windows shim)
|
|
56
|
+
// <npm-prefix>\copilot.ps1 (PowerShell shim)
|
|
57
|
+
// <npm-prefix>\node_modules\@github\copilot\node_modules\@github\copilot-win32-x64\copilot.exe
|
|
58
|
+
// Probe for the platform package next to the shim dir. Returning
|
|
59
|
+
// the .exe means spawnCaptured can use shell: false, side-stepping
|
|
60
|
+
// cmd.exe arg mangling.
|
|
61
|
+
const exeUnderShim = (shim) => join(dirname(shim), 'node_modules', '@github', 'copilot', 'node_modules', '@github', 'copilot-win32-x64', 'copilot.exe');
|
|
62
|
+
for (const shim of candidates) {
|
|
63
|
+
const probed = exeUnderShim(shim);
|
|
64
|
+
if (existsSync(probed))
|
|
65
|
+
return probed;
|
|
66
|
+
}
|
|
67
|
+
// Last resort on Windows: if `where.exe` returned at least one
|
|
68
|
+
// shim path, prefer its absolute form (still a shim, but at least
|
|
69
|
+
// not a bare name -- caller can handle it).
|
|
70
|
+
if (candidates.length > 0)
|
|
71
|
+
return candidates[0];
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
// ``command -v`` is the POSIX-portable equivalent of ``which``;
|
|
75
|
+
// built into every shell, no external binary needed. ``execSync``
|
|
76
|
+
// already wraps the command string in ``/bin/sh -c``, so we can
|
|
77
|
+
// call the shell builtin directly.
|
|
78
|
+
const posixPath = execSync('command -v copilot 2>/dev/null', { encoding: 'utf-8' })
|
|
79
|
+
.trim();
|
|
80
|
+
if (posixPath)
|
|
81
|
+
return posixPath;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch { /* not found */ }
|
|
85
|
+
return 'copilot';
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Given a path to an .agent.md file, parse its frontmatter and return the
|
|
89
|
+
* agent's display name. Falls back to the filename slug if no `name:` is set.
|
|
90
|
+
*/
|
|
91
|
+
export async function resolveAgentDisplayNameFromPath(agentFilePath) {
|
|
92
|
+
const meta = parseAgentFrontmatter(agentFilePath);
|
|
93
|
+
const fallback = basename(agentFilePath).replace(/\.agent\.md$/i, '');
|
|
94
|
+
return meta.name ?? fallback;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=resolve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/copilot/resolve.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAE/D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,iBAAiB;IAC/B,IAAI,GAAG,CAAC,gBAAgB;QAAE,OAAO,GAAG,CAAC,gBAAgB,CAAC;IAEtD,MAAM,SAAS,GAAG,QAAQ,EAAE,KAAK,OAAO,CAAC;IAEzC,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,UAAU,GAAG,IAAI,CACrB,GAAG,CAAC,YAAY,IAAI,EAAE,EACtB,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,CAC9C,CAAC;QACF,IAAI,UAAU,CAAC,UAAU,CAAC;YAAE,OAAO,UAAU,CAAC;IAChD,CAAC;IAED,IAAI,CAAC;QACH,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,UAAU,GAAG,QAAQ,CAAC,yBAAyB,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;iBAC1E,KAAK,CAAC,IAAI,CAAC;iBACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;iBACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC;YAE/D,6DAA6D;YAC7D,0CAA0C;YAC1C,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;YAC3E,IAAI,SAAS;gBAAE,OAAO,SAAS,CAAC;YAEhC,qCAAqC;YACrC,kEAAkE;YAClE,gDAAgD;YAChD,mDAAmD;YACnD,iGAAiG;YACjG,iEAAiE;YACjE,mEAAmE;YACnE,wBAAwB;YACxB,MAAM,YAAY,GAAG,CAAC,IAAY,EAAU,EAAE,CAC5C,IAAI,CACF,OAAO,CAAC,IAAI,CAAC,EACb,cAAc,EAAE,SAAS,EAAE,SAAS,EACpC,cAAc,EAAE,SAAS,EAAE,mBAAmB,EAC9C,aAAa,CACd,CAAC;YACJ,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;gBAC9B,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;gBAClC,IAAI,UAAU,CAAC,MAAM,CAAC;oBAAE,OAAO,MAAM,CAAC;YACxC,CAAC;YAED,+DAA+D;YAC/D,kEAAkE;YAClE,4CAA4C;YAC5C,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;gBAAE,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC;QAClD,CAAC;aAAM,CAAC;YACN,gEAAgE;YAChE,kEAAkE;YAClE,gEAAgE;YAChE,mCAAmC;YACnC,MAAM,SAAS,GAAG,QAAQ,CAAC,gCAAgC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;iBAChF,IAAI,EAAE,CAAC;YACV,IAAI,SAAS;gBAAE,OAAO,SAAS,CAAC;QAClC,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC;IAE3B,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,+BAA+B,CAAC,aAAqB;IACzE,MAAM,IAAI,GAAG,qBAAqB,CAAC,aAAa,CAAC,CAAC;IAClD,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;IACtE,OAAO,IAAI,CAAC,IAAI,IAAI,QAAQ,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spawn helpers for Copilot CLI processes.
|
|
3
|
+
* Two variants:
|
|
4
|
+
* - spawnInteractive: stdio inherited (TTY pass-through), for interactive chat
|
|
5
|
+
* - spawnCaptured: piped stdio with bounded buffer + timeout, for headless run
|
|
6
|
+
*/
|
|
7
|
+
import { spawn as nodeSpawn } from 'node:child_process';
|
|
8
|
+
export interface SpawnInteractiveSpec {
|
|
9
|
+
bin: string;
|
|
10
|
+
args: string[];
|
|
11
|
+
cwd: string;
|
|
12
|
+
env?: Record<string, string>;
|
|
13
|
+
}
|
|
14
|
+
export interface SpawnInteractiveResult {
|
|
15
|
+
exitCode: number;
|
|
16
|
+
durationMs: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Spawn a process with stdio: 'inherit' (TTY pass-through). Returns when the
|
|
20
|
+
* process exits. This function is intentionally dumb -- no banner, no session
|
|
21
|
+
* logic, no MCP wiring. All of that lives in the caller (chat.ts).
|
|
22
|
+
*/
|
|
23
|
+
export declare function spawnInteractive(spec: SpawnInteractiveSpec): Promise<SpawnInteractiveResult>;
|
|
24
|
+
export interface SpawnCapturedSpec {
|
|
25
|
+
bin: string;
|
|
26
|
+
args: string[];
|
|
27
|
+
cwd: string;
|
|
28
|
+
env?: Record<string, string>;
|
|
29
|
+
}
|
|
30
|
+
export interface SpawnCapturedOpts {
|
|
31
|
+
timeoutMs?: number;
|
|
32
|
+
/** Hard cap on bytes retained in memory per stream. Default 1MB. */
|
|
33
|
+
bufferCapBytes?: number;
|
|
34
|
+
/** Bytes of the captured buffer to include in stdoutTail/stderrTail. Defaults to bufferCapBytes. */
|
|
35
|
+
tailBytes?: number;
|
|
36
|
+
onStdout?: (chunk: string) => void;
|
|
37
|
+
onStderr?: (chunk: string) => void;
|
|
38
|
+
/** Inject spawn function (for tests). Defaults to node:child_process spawn. */
|
|
39
|
+
spawnFn?: typeof nodeSpawn;
|
|
40
|
+
}
|
|
41
|
+
export interface SpawnCapturedResult {
|
|
42
|
+
exitCode: number;
|
|
43
|
+
durationMs: number;
|
|
44
|
+
timedOut: boolean;
|
|
45
|
+
stdout: string;
|
|
46
|
+
stderr: string;
|
|
47
|
+
stdoutTail: string;
|
|
48
|
+
stderrTail: string;
|
|
49
|
+
}
|
|
50
|
+
export declare function spawnCaptured(spec: SpawnCapturedSpec, opts?: SpawnCapturedOpts): Promise<SpawnCapturedResult>;
|
|
51
|
+
//# sourceMappingURL=spawn.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../src/copilot/spawn.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAGxD,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AA6BD;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAalG;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oEAAoE;IACpE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oGAAoG;IACpG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,+EAA+E;IAC/E,OAAO,CAAC,EAAE,OAAO,SAAS,CAAC;CAC5B;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,aAAa,CAC3B,IAAI,EAAE,iBAAiB,EACvB,IAAI,GAAE,iBAAsB,GAC3B,OAAO,CAAC,mBAAmB,CAAC,CA6E9B"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spawn helpers for Copilot CLI processes.
|
|
3
|
+
* Two variants:
|
|
4
|
+
* - spawnInteractive: stdio inherited (TTY pass-through), for interactive chat
|
|
5
|
+
* - spawnCaptured: piped stdio with bounded buffer + timeout, for headless run
|
|
6
|
+
*/
|
|
7
|
+
import { spawn as nodeSpawn } from 'node:child_process';
|
|
8
|
+
import { platform } from 'node:os';
|
|
9
|
+
/**
|
|
10
|
+
* Heuristic: do we need `shell: true` to spawn this binary on Windows?
|
|
11
|
+
*
|
|
12
|
+
* Node's `child_process.spawn` on Windows can resolve `.exe` files directly
|
|
13
|
+
* via CreateProcess, but `.cmd` / `.bat` shims (used by every npm-global
|
|
14
|
+
* package — `copilot.cmd`, `claude.cmd`, etc.) require a shell context.
|
|
15
|
+
* Enabling `shell: true` unconditionally works but it (a) drags `cmd.exe`
|
|
16
|
+
* into the call chain, which mangles arg quoting (breaks our tests that
|
|
17
|
+
* pass paths with spaces), and (b) changes exit-code propagation for
|
|
18
|
+
* children that exit non-zero.
|
|
19
|
+
*
|
|
20
|
+
* Compromise: turn `shell` on only when the bin is a bare name OR ends in
|
|
21
|
+
* `.cmd`/`.bat`. Absolute paths to `.exe` files (e.g. `process.execPath`)
|
|
22
|
+
* skip the shell entirely.
|
|
23
|
+
*
|
|
24
|
+
* POSIX always returns false — `.cmd` shims don't exist there.
|
|
25
|
+
*/
|
|
26
|
+
function needsShellOnWindows(bin) {
|
|
27
|
+
if (platform() !== 'win32')
|
|
28
|
+
return false;
|
|
29
|
+
const lower = bin.toLowerCase();
|
|
30
|
+
if (lower.endsWith('.exe'))
|
|
31
|
+
return false;
|
|
32
|
+
// Bare names ('copilot', 'claude') OR explicit shim extensions.
|
|
33
|
+
return !bin.includes('\\') && !bin.includes('/')
|
|
34
|
+
|| lower.endsWith('.cmd')
|
|
35
|
+
|| lower.endsWith('.bat');
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Spawn a process with stdio: 'inherit' (TTY pass-through). Returns when the
|
|
39
|
+
* process exits. This function is intentionally dumb -- no banner, no session
|
|
40
|
+
* logic, no MCP wiring. All of that lives in the caller (chat.ts).
|
|
41
|
+
*/
|
|
42
|
+
export async function spawnInteractive(spec) {
|
|
43
|
+
const startTime = Date.now();
|
|
44
|
+
const child = nodeSpawn(spec.bin, spec.args, {
|
|
45
|
+
cwd: spec.cwd,
|
|
46
|
+
stdio: 'inherit',
|
|
47
|
+
shell: needsShellOnWindows(spec.bin),
|
|
48
|
+
...(spec.env ? { env: { ...process.env, ...spec.env } } : {}),
|
|
49
|
+
});
|
|
50
|
+
const exitCode = await new Promise((resolveP, rejectP) => {
|
|
51
|
+
child.on('exit', (code) => resolveP(code));
|
|
52
|
+
child.on('error', (err) => rejectP(err));
|
|
53
|
+
});
|
|
54
|
+
return { exitCode: exitCode ?? 1, durationMs: Date.now() - startTime };
|
|
55
|
+
}
|
|
56
|
+
export function spawnCaptured(spec, opts = {}) {
|
|
57
|
+
return new Promise((resolveP) => {
|
|
58
|
+
const startTime = Date.now();
|
|
59
|
+
const cap = opts.bufferCapBytes ?? 1024 * 1024;
|
|
60
|
+
const spawnFn = opts.spawnFn ?? nodeSpawn;
|
|
61
|
+
// Bounded FIFO buffer: peak memory is at most ~2*cap (during a single
|
|
62
|
+
// chunk merge) before the slice trims back to `cap`. Prevents unbounded
|
|
63
|
+
// growth on agents that produce gigabytes of stdout.
|
|
64
|
+
const append = (current, chunk) => {
|
|
65
|
+
if (chunk.length >= cap)
|
|
66
|
+
return chunk.slice(-cap);
|
|
67
|
+
const overflow = current.length + chunk.length - cap;
|
|
68
|
+
if (overflow <= 0)
|
|
69
|
+
return current + chunk;
|
|
70
|
+
return current.slice(overflow) + chunk;
|
|
71
|
+
};
|
|
72
|
+
const child = spawnFn(spec.bin, spec.args, {
|
|
73
|
+
cwd: spec.cwd,
|
|
74
|
+
// shell:true is only needed on Windows to resolve `.cmd` shims
|
|
75
|
+
// (e.g. copilot.cmd on PATH). On posix it adds an extra `/bin/sh`
|
|
76
|
+
// layer that changes argv semantics and broadens the injection
|
|
77
|
+
// surface for caller-controlled values like options.model.
|
|
78
|
+
shell: platform() === 'win32',
|
|
79
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
80
|
+
...(spec.env ? { env: { ...process.env, ...spec.env } } : {}),
|
|
81
|
+
});
|
|
82
|
+
let stdout = '';
|
|
83
|
+
let stderr = '';
|
|
84
|
+
let timedOut = false;
|
|
85
|
+
let escalationTimer;
|
|
86
|
+
child.stdout?.on('data', (data) => {
|
|
87
|
+
const chunk = data.toString();
|
|
88
|
+
stdout = append(stdout, chunk);
|
|
89
|
+
opts.onStdout?.(chunk);
|
|
90
|
+
});
|
|
91
|
+
child.stderr?.on('data', (data) => {
|
|
92
|
+
const chunk = data.toString();
|
|
93
|
+
stderr = append(stderr, chunk);
|
|
94
|
+
opts.onStderr?.(chunk);
|
|
95
|
+
});
|
|
96
|
+
const timer = opts.timeoutMs
|
|
97
|
+
? setTimeout(() => {
|
|
98
|
+
timedOut = true;
|
|
99
|
+
child.kill('SIGTERM');
|
|
100
|
+
// Belt and suspenders: if SIGTERM doesn't take, escalate after 5s.
|
|
101
|
+
escalationTimer = setTimeout(() => {
|
|
102
|
+
if (child.exitCode === null)
|
|
103
|
+
child.kill('SIGKILL');
|
|
104
|
+
}, 5000);
|
|
105
|
+
escalationTimer.unref();
|
|
106
|
+
}, opts.timeoutMs)
|
|
107
|
+
: undefined;
|
|
108
|
+
const finish = (code) => {
|
|
109
|
+
if (timer)
|
|
110
|
+
clearTimeout(timer);
|
|
111
|
+
if (escalationTimer)
|
|
112
|
+
clearTimeout(escalationTimer);
|
|
113
|
+
const durationMs = Date.now() - startTime;
|
|
114
|
+
const tail = opts.tailBytes ?? cap;
|
|
115
|
+
resolveP({
|
|
116
|
+
exitCode: code ?? 1,
|
|
117
|
+
durationMs,
|
|
118
|
+
timedOut,
|
|
119
|
+
stdout,
|
|
120
|
+
stderr,
|
|
121
|
+
stdoutTail: stdout.length > tail ? stdout.slice(-tail) : stdout,
|
|
122
|
+
stderrTail: stderr.length > tail ? stderr.slice(-tail) : stderr,
|
|
123
|
+
});
|
|
124
|
+
};
|
|
125
|
+
child.on('exit', (code) => finish(code));
|
|
126
|
+
child.on('error', (err) => {
|
|
127
|
+
stderr += `\n[loom-run] spawn error: ${err.message}`;
|
|
128
|
+
finish(1);
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=spawn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spawn.js","sourceRoot":"","sources":["../../src/copilot/spawn.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAcnC;;;;;;;;;;;;;;;;GAgBG;AACH,SAAS,mBAAmB,CAAC,GAAW;IACtC,IAAI,QAAQ,EAAE,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IACzC,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;IAChC,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IACzC,gEAAgE;IAChE,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC;WAC3C,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;WACtB,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAC9B,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAA0B;IAC/D,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE;QAC3C,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,KAAK,EAAE,SAAS;QAChB,KAAK,EAAE,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC;QACpC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC9D,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,MAAM,IAAI,OAAO,CAAgB,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE;QACtE,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3C,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,QAAQ,EAAE,QAAQ,IAAI,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,EAAE,CAAC;AACzE,CAAC;AA+BD,MAAM,UAAU,aAAa,CAC3B,IAAuB,EACvB,OAA0B,EAAE;IAE5B,OAAO,IAAI,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;QAC9B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,IAAI,IAAI,GAAG,IAAI,CAAC;QAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,SAAS,CAAC;QAE1C,sEAAsE;QACtE,wEAAwE;QACxE,qDAAqD;QACrD,MAAM,MAAM,GAAG,CAAC,OAAe,EAAE,KAAa,EAAU,EAAE;YACxD,IAAI,KAAK,CAAC,MAAM,IAAI,GAAG;gBAAE,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC;YAClD,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC;YACrD,IAAI,QAAQ,IAAI,CAAC;gBAAE,OAAO,OAAO,GAAG,KAAK,CAAC;YAC1C,OAAO,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC;QACzC,CAAC,CAAC;QAEF,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE;YACzC,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,+DAA+D;YAC/D,kEAAkE;YAClE,+DAA+D;YAC/D,2DAA2D;YAC3D,KAAK,EAAE,QAAQ,EAAE,KAAK,OAAO;YAC7B,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;YAC/B,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9D,CAAC,CAAC;QAEH,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,IAAI,eAA2C,CAAC;QAEhD,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;YACxC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC9B,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YAC/B,IAAI,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;YACxC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC9B,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YAC/B,IAAI,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS;YAC1B,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE;gBACd,QAAQ,GAAG,IAAI,CAAC;gBAChB,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACtB,mEAAmE;gBACnE,eAAe,GAAG,UAAU,CAAC,GAAG,EAAE;oBAChC,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI;wBAAE,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACrD,CAAC,EAAE,IAAI,CAAC,CAAC;gBACT,eAAe,CAAC,KAAK,EAAE,CAAC;YAC1B,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC;YACpB,CAAC,CAAC,SAAS,CAAC;QAEd,MAAM,MAAM,GAAG,CAAC,IAAmB,EAAE,EAAE;YACrC,IAAI,KAAK;gBAAE,YAAY,CAAC,KAAK,CAAC,CAAC;YAC/B,IAAI,eAAe;gBAAE,YAAY,CAAC,eAAe,CAAC,CAAC;YACnD,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,IAAI,GAAG,CAAC;YACnC,QAAQ,CAAC;gBACP,QAAQ,EAAE,IAAI,IAAI,CAAC;gBACnB,UAAU;gBACV,QAAQ;gBACR,MAAM;gBACN,MAAM;gBACN,UAAU,EAAE,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM;gBAC/D,UAAU,EAAE,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM;aAChE,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QACzC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACxB,MAAM,IAAI,6BAA6B,GAAG,CAAC,OAAO,EAAE,CAAC;YACrD,MAAM,CAAC,CAAC,CAAC,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main library entry point for @agent-loom/loom.
|
|
3
|
+
*
|
|
4
|
+
* This is the public SDK surface. CLI entry is `src/cli.ts`.
|
|
5
|
+
*
|
|
6
|
+
* Subpath exports (see `package.json` exports map):
|
|
7
|
+
* - `@agent-loom/loom` (this file — chat + run + staging + types)
|
|
8
|
+
* - `@agent-loom/loom/run` (headless `run()` only)
|
|
9
|
+
* - `@agent-loom/loom/launch` (`stageRegistryAgent` for orchestrators)
|
|
10
|
+
* - `@agent-loom/loom/acp` (`AcpClient` for the planned peers MCP)
|
|
11
|
+
*/
|
|
12
|
+
export { chat, buildChatCommand, defaultPreChatBanner } from './chat/index.js';
|
|
13
|
+
export type { ChatOptions, ChatResult, LaunchRuntimeKind, PreLaunchInfo, } from './chat/index.js';
|
|
14
|
+
export { run, DEFAULT_RUN_TIMEOUT_MS } from './run/index.js';
|
|
15
|
+
export type { RunOptions, RunResult } from './run/index.js';
|
|
16
|
+
export { stageRegistryAgent } from './launch/index.js';
|
|
17
|
+
export type { StagedLaunch, StageOptions } from './launch/index.js';
|
|
18
|
+
export type { McpServerConfig } from './copilot/mcp.js';
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAC/E,YAAY,EACV,WAAW,EACX,UAAU,EACV,iBAAiB,EACjB,aAAa,GACd,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,GAAG,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAC7D,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIpE,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main library entry point for @agent-loom/loom.
|
|
3
|
+
*
|
|
4
|
+
* This is the public SDK surface. CLI entry is `src/cli.ts`.
|
|
5
|
+
*
|
|
6
|
+
* Subpath exports (see `package.json` exports map):
|
|
7
|
+
* - `@agent-loom/loom` (this file — chat + run + staging + types)
|
|
8
|
+
* - `@agent-loom/loom/run` (headless `run()` only)
|
|
9
|
+
* - `@agent-loom/loom/launch` (`stageRegistryAgent` for orchestrators)
|
|
10
|
+
* - `@agent-loom/loom/acp` (`AcpClient` for the planned peers MCP)
|
|
11
|
+
*/
|
|
12
|
+
export { chat, buildChatCommand, defaultPreChatBanner } from './chat/index.js';
|
|
13
|
+
export { run, DEFAULT_RUN_TIMEOUT_MS } from './run/index.js';
|
|
14
|
+
export { stageRegistryAgent } from './launch/index.js';
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAQ/E,OAAO,EAAE,GAAG,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAG7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public exports for the launch module.
|
|
3
|
+
*
|
|
4
|
+
* `launch` is the layer between registry resolution and runtime spawn:
|
|
5
|
+
* it materializes a registry-resolved agent into a session workspace
|
|
6
|
+
* ready for `chat()`, `run()`, or a future `startSpecialist()`.
|
|
7
|
+
*/
|
|
8
|
+
export { stageRegistryAgent } from './stage.js';
|
|
9
|
+
export type { StagedLaunch, StageOptions } from './stage.js';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/launch/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public exports for the launch module.
|
|
3
|
+
*
|
|
4
|
+
* `launch` is the layer between registry resolution and runtime spawn:
|
|
5
|
+
* it materializes a registry-resolved agent into a session workspace
|
|
6
|
+
* ready for `chat()`, `run()`, or a future `startSpecialist()`.
|
|
7
|
+
*/
|
|
8
|
+
export { stageRegistryAgent } from './stage.js';
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/launch/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Staging — materialize a registry-resolved agent into a session workspace.
|
|
3
|
+
*
|
|
4
|
+
* The staging flow:
|
|
5
|
+
* 1. Generate a session id + compute the staged workspace path
|
|
6
|
+
* 2. Create the session record pointing at that workspace
|
|
7
|
+
* 3. Apply the registry template into `<session.dir>/workspace/`
|
|
8
|
+
* 4. Return a `ResolvedAgentRef` pointing at the staged agent file so the
|
|
9
|
+
* launch machinery can spawn against it unchanged.
|
|
10
|
+
*
|
|
11
|
+
* Manifest repos are cloned in `'auto'` mode by default — real-work agents
|
|
12
|
+
* (CRI triage, pool investigations, ...) reference these repos at runtime
|
|
13
|
+
* and a session without them stalls immediately. Lightweight callers can
|
|
14
|
+
* pass `cloneRepos: 'none'` to skip.
|
|
15
|
+
*
|
|
16
|
+
* Located under `src/launch/` (not `src/chat/`) so library consumers like
|
|
17
|
+
* `loom run`, the planned `startSpecialist` (#76), and `loom-peers-mcp`
|
|
18
|
+
* (#77) can stage without pulling in chat-only modules.
|
|
19
|
+
*/
|
|
20
|
+
import { type Session, type SessionRuntime } from '../sessions/index.js';
|
|
21
|
+
import type { ResolvedAgentRef } from '../chat/resolve-agent.js';
|
|
22
|
+
import type { RegistryAgentHit } from '../chat/registry.js';
|
|
23
|
+
export interface StagedLaunch {
|
|
24
|
+
/** The session record that owns the staged workspace. */
|
|
25
|
+
session: Session;
|
|
26
|
+
/** The staged agent ref — points inside `<session.dir>/workspace/`. */
|
|
27
|
+
agent: ResolvedAgentRef;
|
|
28
|
+
}
|
|
29
|
+
export interface StageOptions {
|
|
30
|
+
hit: RegistryAgentHit;
|
|
31
|
+
/** Friendly session label. */
|
|
32
|
+
sessionName?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Runtime the staged session will be launched against. Controls both the
|
|
35
|
+
* `runtime:` field on the session record AND the renderer (`target`) used
|
|
36
|
+
* by `applyTemplate`. Defaults to `'copilot'` for back-compat with the
|
|
37
|
+
* pre-multi-runtime callers, but new callers should pass this through
|
|
38
|
+
* from the user's `--runtime` choice.
|
|
39
|
+
*/
|
|
40
|
+
runtime?: SessionRuntime;
|
|
41
|
+
/** Progress callback forwarded to applyTemplate. */
|
|
42
|
+
onProgress?: (msg: string) => void;
|
|
43
|
+
/**
|
|
44
|
+
* Manifest repo clone behavior. Defaults to `'auto'` for staged launches
|
|
45
|
+
* because real-work agents reference repos at runtime
|
|
46
|
+
* and a workspace without them is dead-on-arrival. Pass `'none'` for
|
|
47
|
+
* lightweight / smoke-test agents.
|
|
48
|
+
*/
|
|
49
|
+
cloneRepos?: 'auto' | 'all' | 'none';
|
|
50
|
+
/** Clone strategy override forwarded to applyTemplate. */
|
|
51
|
+
cloneMode?: 'full' | 'partial';
|
|
52
|
+
/** Interactive prompt for large/ADO repos (forwarded to applyTemplate). */
|
|
53
|
+
promptFn?: (message: string, choices: string[]) => Promise<string>;
|
|
54
|
+
/** Junction/symlink creator (forwarded to applyTemplate). */
|
|
55
|
+
linkFn?: (target: string, linkPath: string) => Promise<void>;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Stage a registry-resolved agent into a new session workspace, ready to launch.
|
|
59
|
+
* Throws if `applyTemplate` fails to produce the expected agent file.
|
|
60
|
+
*/
|
|
61
|
+
export declare function stageRegistryAgent(options: StageOptions): Promise<StagedLaunch>;
|
|
62
|
+
//# sourceMappingURL=stage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stage.d.ts","sourceRoot":"","sources":["../../src/launch/stage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAMH,OAAO,EAML,KAAK,OAAO,EACZ,KAAK,cAAc,EACpB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,MAAM,WAAW,YAAY;IAC3B,yDAAyD;IACzD,OAAO,EAAE,OAAO,CAAC;IACjB,uEAAuE;IACvE,KAAK,EAAE,gBAAgB,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,gBAAgB,CAAC;IACtB,8BAA8B;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,oDAAoD;IACpD,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;IACrC,0DAA0D;IAC1D,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACnE,6DAA6D;IAC7D,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9D;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CA4FrF"}
|