@agents-dev/cli 0.7.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (152) hide show
  1. package/AGENTS.md +400 -0
  2. package/CHANGELOG.md +297 -0
  3. package/CONTRIBUTING.md +164 -0
  4. package/LICENSE +21 -0
  5. package/README.md +117 -0
  6. package/bin/agents +24 -0
  7. package/dist/cli.d.ts +1 -0
  8. package/dist/cli.js +282 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/commands/connect.d.ts +7 -0
  11. package/dist/commands/connect.js +48 -0
  12. package/dist/commands/connect.js.map +1 -0
  13. package/dist/commands/disconnect.d.ts +7 -0
  14. package/dist/commands/disconnect.js +47 -0
  15. package/dist/commands/disconnect.js.map +1 -0
  16. package/dist/commands/doctor.d.ts +6 -0
  17. package/dist/commands/doctor.js +430 -0
  18. package/dist/commands/doctor.js.map +1 -0
  19. package/dist/commands/init.d.ts +5 -0
  20. package/dist/commands/init.js +24 -0
  21. package/dist/commands/init.js.map +1 -0
  22. package/dist/commands/mcp-add.d.ts +20 -0
  23. package/dist/commands/mcp-add.js +250 -0
  24. package/dist/commands/mcp-add.js.map +1 -0
  25. package/dist/commands/mcp-import.d.ts +13 -0
  26. package/dist/commands/mcp-import.js +207 -0
  27. package/dist/commands/mcp-import.js.map +1 -0
  28. package/dist/commands/mcp-list.d.ts +5 -0
  29. package/dist/commands/mcp-list.js +34 -0
  30. package/dist/commands/mcp-list.js.map +1 -0
  31. package/dist/commands/mcp-remove.d.ts +7 -0
  32. package/dist/commands/mcp-remove.js +34 -0
  33. package/dist/commands/mcp-remove.js.map +1 -0
  34. package/dist/commands/mcp-test.d.ts +8 -0
  35. package/dist/commands/mcp-test.js +402 -0
  36. package/dist/commands/mcp-test.js.map +1 -0
  37. package/dist/commands/reset.d.ts +6 -0
  38. package/dist/commands/reset.js +76 -0
  39. package/dist/commands/reset.js.map +1 -0
  40. package/dist/commands/start.d.ts +6 -0
  41. package/dist/commands/start.js +292 -0
  42. package/dist/commands/start.js.map +1 -0
  43. package/dist/commands/status.d.ts +7 -0
  44. package/dist/commands/status.js +278 -0
  45. package/dist/commands/status.js.map +1 -0
  46. package/dist/commands/sync.d.ts +6 -0
  47. package/dist/commands/sync.js +22 -0
  48. package/dist/commands/sync.js.map +1 -0
  49. package/dist/commands/watch.d.ts +7 -0
  50. package/dist/commands/watch.js +117 -0
  51. package/dist/commands/watch.js.map +1 -0
  52. package/dist/core/claudeCli.d.ts +7 -0
  53. package/dist/core/claudeCli.js +35 -0
  54. package/dist/core/claudeCli.js.map +1 -0
  55. package/dist/core/config.d.ts +17 -0
  56. package/dist/core/config.js +121 -0
  57. package/dist/core/config.js.map +1 -0
  58. package/dist/core/cursorCli.d.ts +9 -0
  59. package/dist/core/cursorCli.js +60 -0
  60. package/dist/core/cursorCli.js.map +1 -0
  61. package/dist/core/fs.d.ts +11 -0
  62. package/dist/core/fs.js +76 -0
  63. package/dist/core/fs.js.map +1 -0
  64. package/dist/core/gitignore.d.ts +3 -0
  65. package/dist/core/gitignore.js +54 -0
  66. package/dist/core/gitignore.js.map +1 -0
  67. package/dist/core/mcp.d.ts +8 -0
  68. package/dist/core/mcp.js +134 -0
  69. package/dist/core/mcp.js.map +1 -0
  70. package/dist/core/mcpCrud.d.ts +34 -0
  71. package/dist/core/mcpCrud.js +105 -0
  72. package/dist/core/mcpCrud.js.map +1 -0
  73. package/dist/core/mcpImport.d.ts +14 -0
  74. package/dist/core/mcpImport.js +507 -0
  75. package/dist/core/mcpImport.js.map +1 -0
  76. package/dist/core/mcpSecrets.d.ts +27 -0
  77. package/dist/core/mcpSecrets.js +144 -0
  78. package/dist/core/mcpSecrets.js.map +1 -0
  79. package/dist/core/mcpValidation.d.ts +19 -0
  80. package/dist/core/mcpValidation.js +78 -0
  81. package/dist/core/mcpValidation.js.map +1 -0
  82. package/dist/core/paths.d.ts +37 -0
  83. package/dist/core/paths.js +43 -0
  84. package/dist/core/paths.js.map +1 -0
  85. package/dist/core/project.d.ts +16 -0
  86. package/dist/core/project.js +34 -0
  87. package/dist/core/project.js.map +1 -0
  88. package/dist/core/renderers.d.ts +14 -0
  89. package/dist/core/renderers.js +113 -0
  90. package/dist/core/renderers.js.map +1 -0
  91. package/dist/core/shell.d.ts +8 -0
  92. package/dist/core/shell.js +21 -0
  93. package/dist/core/shell.js.map +1 -0
  94. package/dist/core/shellWords.d.ts +1 -0
  95. package/dist/core/shellWords.js +84 -0
  96. package/dist/core/shellWords.js.map +1 -0
  97. package/dist/core/skills.d.ts +8 -0
  98. package/dist/core/skills.js +150 -0
  99. package/dist/core/skills.js.map +1 -0
  100. package/dist/core/skillsValidation.d.ts +1 -0
  101. package/dist/core/skillsValidation.js +68 -0
  102. package/dist/core/skillsValidation.js.map +1 -0
  103. package/dist/core/sync.d.ts +2 -0
  104. package/dist/core/sync.js +427 -0
  105. package/dist/core/sync.js.map +1 -0
  106. package/dist/core/syncLock.d.ts +1 -0
  107. package/dist/core/syncLock.js +84 -0
  108. package/dist/core/syncLock.js.map +1 -0
  109. package/dist/core/templates.d.ts +1 -0
  110. package/dist/core/templates.js +38 -0
  111. package/dist/core/templates.js.map +1 -0
  112. package/dist/core/trust.d.ts +7 -0
  113. package/dist/core/trust.js +51 -0
  114. package/dist/core/trust.js.map +1 -0
  115. package/dist/core/vscodeSettings.d.ts +17 -0
  116. package/dist/core/vscodeSettings.js +212 -0
  117. package/dist/core/vscodeSettings.js.map +1 -0
  118. package/dist/core/warnings.d.ts +2 -0
  119. package/dist/core/warnings.js +26 -0
  120. package/dist/core/warnings.js.map +1 -0
  121. package/dist/integrations/antigravity.d.ts +9 -0
  122. package/dist/integrations/antigravity.js +13 -0
  123. package/dist/integrations/antigravity.js.map +1 -0
  124. package/dist/integrations/claude.d.ts +1 -0
  125. package/dist/integrations/claude.js +4 -0
  126. package/dist/integrations/claude.js.map +1 -0
  127. package/dist/integrations/codex.d.ts +5 -0
  128. package/dist/integrations/codex.js +5 -0
  129. package/dist/integrations/codex.js.map +1 -0
  130. package/dist/integrations/copilotVscode.d.ts +7 -0
  131. package/dist/integrations/copilotVscode.js +9 -0
  132. package/dist/integrations/copilotVscode.js.map +1 -0
  133. package/dist/integrations/cursor.d.ts +7 -0
  134. package/dist/integrations/cursor.js +9 -0
  135. package/dist/integrations/cursor.js.map +1 -0
  136. package/dist/integrations/gemini.d.ts +12 -0
  137. package/dist/integrations/gemini.js +15 -0
  138. package/dist/integrations/gemini.js.map +1 -0
  139. package/dist/integrations/registry.d.ts +9 -0
  140. package/dist/integrations/registry.js +21 -0
  141. package/dist/integrations/registry.js.map +1 -0
  142. package/dist/types.d.ts +85 -0
  143. package/dist/types.js +2 -0
  144. package/dist/types.js.map +1 -0
  145. package/docs/EXAMPLES.md +211 -0
  146. package/docs/README.md +26 -0
  147. package/docs/agents-system.md +178 -0
  148. package/package.json +77 -0
  149. package/templates/agents/AGENTS.md +23 -0
  150. package/templates/agents/README.md +25 -0
  151. package/templates/agents/skills/README.md +27 -0
  152. package/templates/agents/skills/skill-guide/SKILL.md +29 -0
@@ -0,0 +1,7 @@
1
+ export interface WatchOptions {
2
+ projectRoot: string;
3
+ intervalMs: number;
4
+ once: boolean;
5
+ quiet: boolean;
6
+ }
7
+ export declare function runWatch(options: WatchOptions): Promise<void>;
@@ -0,0 +1,117 @@
1
+ import path from 'node:path';
2
+ import { lstat, readdir } from 'node:fs/promises';
3
+ import { performSync } from '../core/sync.js';
4
+ import { getProjectPaths } from '../core/paths.js';
5
+ import { pathExists } from '../core/fs.js';
6
+ import { formatWarnings } from '../core/warnings.js';
7
+ export async function runWatch(options) {
8
+ const projectRoot = path.resolve(options.projectRoot);
9
+ const intervalMs = normalizeInterval(options.intervalMs);
10
+ if (options.once) {
11
+ await runSingleSync(projectRoot, options.quiet);
12
+ return;
13
+ }
14
+ process.stdout.write(`Watching .agents files in ${projectRoot} (interval ${intervalMs}ms)\n`);
15
+ process.stdout.write('Press Ctrl+C to stop.\n');
16
+ let lastSignature = await snapshotSignature(projectRoot);
17
+ let stopped = false;
18
+ const stop = () => {
19
+ stopped = true;
20
+ };
21
+ process.on('SIGINT', stop);
22
+ process.on('SIGTERM', stop);
23
+ while (!stopped) {
24
+ await sleep(intervalMs);
25
+ const nextSignature = await snapshotSignature(projectRoot);
26
+ if (nextSignature === lastSignature)
27
+ continue;
28
+ lastSignature = nextSignature;
29
+ await runSingleSync(projectRoot, options.quiet);
30
+ }
31
+ process.stdout.write('Watch stopped.\n');
32
+ }
33
+ async function runSingleSync(projectRoot, quiet) {
34
+ const startedAt = new Date().toISOString();
35
+ try {
36
+ const result = await performSync({
37
+ projectRoot,
38
+ check: false,
39
+ verbose: false
40
+ });
41
+ if (quiet && result.changed.length === 0 && result.warnings.length === 0) {
42
+ return;
43
+ }
44
+ process.stdout.write(`[${startedAt}] sync\n`);
45
+ if (result.changed.length === 0) {
46
+ process.stdout.write('No changes.\n');
47
+ }
48
+ else {
49
+ process.stdout.write(`Updated ${result.changed.length} item(s):\n- ${result.changed.join('\n- ')}\n`);
50
+ }
51
+ const warningBlock = formatWarnings(result.warnings, 5);
52
+ if (warningBlock) {
53
+ process.stdout.write(warningBlock);
54
+ }
55
+ }
56
+ catch (error) {
57
+ const message = error instanceof Error ? error.message : String(error);
58
+ process.stdout.write(`[${startedAt}] sync failed: ${message}\n`);
59
+ }
60
+ }
61
+ async function snapshotSignature(projectRoot) {
62
+ const paths = getProjectPaths(projectRoot);
63
+ const parts = await Promise.all([
64
+ fingerprintPath(paths.agentsConfig, 'agents_config'),
65
+ fingerprintPath(paths.rootAgentsMd, 'agents_md'),
66
+ fingerprintPath(paths.agentsLocal, 'local'),
67
+ fingerprintTree(paths.agentsSkillsDir, 'skills')
68
+ ]);
69
+ return parts.join('|');
70
+ }
71
+ async function fingerprintPath(filePath, label) {
72
+ if (!(await pathExists(filePath))) {
73
+ return `${label}:missing`;
74
+ }
75
+ const info = await lstat(filePath);
76
+ const kind = info.isSymbolicLink() ? 'symlink' : info.isDirectory() ? 'dir' : 'file';
77
+ return `${label}:${kind}:${info.size}:${Math.round(info.mtimeMs)}`;
78
+ }
79
+ async function fingerprintTree(rootDir, label) {
80
+ if (!(await pathExists(rootDir))) {
81
+ return `${label}:missing`;
82
+ }
83
+ const entries = [];
84
+ async function walk(currentDir) {
85
+ const children = await readdir(currentDir, { withFileTypes: true });
86
+ children.sort((a, b) => a.name.localeCompare(b.name));
87
+ for (const child of children) {
88
+ const absolute = path.join(currentDir, child.name);
89
+ const relative = path.relative(rootDir, absolute);
90
+ if (child.isDirectory()) {
91
+ entries.push(`d:${relative}`);
92
+ await walk(absolute);
93
+ continue;
94
+ }
95
+ const info = await lstat(absolute);
96
+ const kind = info.isSymbolicLink() ? 'l' : 'f';
97
+ entries.push(`${kind}:${relative}:${info.size}:${Math.round(info.mtimeMs)}`);
98
+ }
99
+ }
100
+ await walk(rootDir);
101
+ return `${label}:${entries.join(',')}`;
102
+ }
103
+ function normalizeInterval(input) {
104
+ if (!Number.isFinite(input))
105
+ return 1200;
106
+ if (input < 200)
107
+ return 200;
108
+ if (input > 60_000)
109
+ return 60_000;
110
+ return Math.floor(input);
111
+ }
112
+ function sleep(ms) {
113
+ return new Promise((resolve) => {
114
+ setTimeout(resolve, ms);
115
+ });
116
+ }
117
+ //# sourceMappingURL=watch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export interface ClaudeMcpListResult {
2
+ ok: boolean;
3
+ names: string[];
4
+ stderr: string;
5
+ }
6
+ export declare function parseClaudeManagedServerNames(output: string, prefix?: string): string[];
7
+ export declare function listClaudeManagedServerNames(projectRoot: string, prefix?: string): ClaudeMcpListResult;
@@ -0,0 +1,35 @@
1
+ import { runCommand } from './shell.js';
2
+ import { sanitizeTerminalOutput } from './cursorCli.js';
3
+ export function parseClaudeManagedServerNames(output, prefix = 'agents__') {
4
+ const names = new Set();
5
+ const lines = sanitizeTerminalOutput(output)
6
+ .split('\n')
7
+ .map((line) => line.trim())
8
+ .filter(Boolean);
9
+ for (const line of lines) {
10
+ const match = line.match(/^([a-zA-Z0-9._:-]+):/);
11
+ if (!match?.[1])
12
+ continue;
13
+ const name = match[1];
14
+ if (!name.startsWith(prefix))
15
+ continue;
16
+ names.add(name);
17
+ }
18
+ return [...names].sort((a, b) => a.localeCompare(b));
19
+ }
20
+ export function listClaudeManagedServerNames(projectRoot, prefix = 'agents__') {
21
+ const result = runCommand('claude', ['mcp', 'list'], projectRoot);
22
+ if (!result.ok) {
23
+ return {
24
+ ok: false,
25
+ names: [],
26
+ stderr: result.stderr
27
+ };
28
+ }
29
+ return {
30
+ ok: true,
31
+ names: parseClaudeManagedServerNames(`${result.stdout}\n${result.stderr}`, prefix),
32
+ stderr: result.stderr
33
+ };
34
+ }
35
+ //# sourceMappingURL=claudeCli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claudeCli.js","sourceRoot":"","sources":["../../src/core/claudeCli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACvC,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAA;AAQvD,MAAM,UAAU,6BAA6B,CAAC,MAAc,EAAE,MAAM,GAAG,UAAU;IAC/E,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAA;IAC/B,MAAM,KAAK,GAAG,sBAAsB,CAAC,MAAM,CAAC;SACzC,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,OAAO,CAAC,CAAA;IAElB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAA;QAChD,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YAAE,SAAQ;QACzB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;QACrB,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;YAAE,SAAQ;QACtC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IACjB,CAAC;IAED,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAA;AACtD,CAAC;AAED,MAAM,UAAU,4BAA4B,CAAC,WAAmB,EAAE,MAAM,GAAG,UAAU;IACnF,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,WAAW,CAAC,CAAA;IACjE,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,OAAO;YACL,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,EAAE;YACT,MAAM,EAAE,MAAM,CAAC,MAAM;SACtB,CAAA;IACH,CAAC;IAED,OAAO;QACL,EAAE,EAAE,IAAI;QACR,KAAK,EAAE,6BAA6B,CAAC,GAAG,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,EAAE,MAAM,CAAC;QAClF,MAAM,EAAE,MAAM,CAAC,MAAM;KACtB,CAAA;AACH,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { AgentsConfig, IntegrationName, McpServerDefinition, SyncMode } from '../types.js';
2
+ export declare const DEFAULT_VSCODE_HIDDEN_PATHS: string[];
3
+ export declare function createDefaultAgentsConfig(args?: {
4
+ enabledIntegrations?: IntegrationName[];
5
+ integrationOptions?: {
6
+ cursorAutoApprove: boolean;
7
+ antigravityGlobalSync: boolean;
8
+ };
9
+ syncMode?: SyncMode;
10
+ hideGenerated?: boolean;
11
+ hiddenPaths?: string[];
12
+ mcpServers?: Record<string, McpServerDefinition>;
13
+ }): AgentsConfig;
14
+ export declare function loadAgentsConfig(projectRoot: string): Promise<AgentsConfig>;
15
+ export declare function saveAgentsConfig(projectRoot: string, config: AgentsConfig): Promise<void>;
16
+ export declare const loadProjectConfig: typeof loadAgentsConfig;
17
+ export declare const saveProjectConfig: typeof saveAgentsConfig;
@@ -0,0 +1,121 @@
1
+ import path from 'node:path';
2
+ import { ensureDir, pathExists, readJson, writeJsonAtomic } from './fs.js';
3
+ import { getProjectPaths } from './paths.js';
4
+ import { AGENTS_SCHEMA_VERSION } from '../types.js';
5
+ export const DEFAULT_VSCODE_HIDDEN_PATHS = [
6
+ '**/.codex',
7
+ '**/.claude',
8
+ '**/.gemini',
9
+ '**/.cursor',
10
+ '**/.antigravity',
11
+ '**/.agents/generated'
12
+ ];
13
+ const DEFAULT_MCP_SERVERS = {
14
+ filesystem: {
15
+ label: 'Filesystem',
16
+ description: 'Read and write files in the current project',
17
+ transport: 'stdio',
18
+ command: 'npx',
19
+ args: ['-y', '@modelcontextprotocol/server-filesystem', '${PROJECT_ROOT}'],
20
+ targets: ['codex', 'claude', 'gemini', 'copilot_vscode', 'cursor', 'antigravity'],
21
+ enabled: true
22
+ },
23
+ fetch: {
24
+ label: 'Fetch',
25
+ description: 'HTTP fetching and scraping helpers',
26
+ transport: 'stdio',
27
+ command: 'uvx',
28
+ args: ['mcp-server-fetch'],
29
+ env: {
30
+ FASTMCP_LOG_LEVEL: 'ERROR'
31
+ },
32
+ targets: ['codex', 'claude', 'gemini', 'copilot_vscode', 'cursor', 'antigravity'],
33
+ enabled: true
34
+ },
35
+ git: {
36
+ label: 'Git',
37
+ description: 'Repository-aware git operations',
38
+ transport: 'stdio',
39
+ command: 'uvx',
40
+ args: ['mcp-server-git', '--repository', '${PROJECT_ROOT}'],
41
+ env: {
42
+ FASTMCP_LOG_LEVEL: 'ERROR'
43
+ },
44
+ targets: ['codex', 'claude', 'gemini', 'copilot_vscode', 'cursor', 'antigravity'],
45
+ enabled: true
46
+ }
47
+ };
48
+ export function createDefaultAgentsConfig(args) {
49
+ return {
50
+ schemaVersion: AGENTS_SCHEMA_VERSION,
51
+ instructions: {
52
+ path: 'AGENTS.md'
53
+ },
54
+ integrations: {
55
+ enabled: [...(args?.enabledIntegrations ?? [])],
56
+ options: {
57
+ cursorAutoApprove: args?.integrationOptions?.cursorAutoApprove !== false,
58
+ antigravityGlobalSync: args?.integrationOptions?.antigravityGlobalSync === true
59
+ }
60
+ },
61
+ syncMode: args?.syncMode ?? 'source-only',
62
+ mcp: {
63
+ servers: JSON.parse(JSON.stringify(args?.mcpServers ?? DEFAULT_MCP_SERVERS))
64
+ },
65
+ workspace: {
66
+ vscode: {
67
+ hideGenerated: args?.hideGenerated !== false,
68
+ hiddenPaths: [...(args?.hiddenPaths ?? DEFAULT_VSCODE_HIDDEN_PATHS)]
69
+ }
70
+ },
71
+ lastSync: null
72
+ };
73
+ }
74
+ export async function loadAgentsConfig(projectRoot) {
75
+ const paths = getProjectPaths(projectRoot);
76
+ if (!(await pathExists(paths.agentsConfig))) {
77
+ throw new Error(`Missing config: ${paths.agentsConfig}. Run "agents start" first.`);
78
+ }
79
+ const config = await readJson(paths.agentsConfig);
80
+ if (config.schemaVersion !== AGENTS_SCHEMA_VERSION) {
81
+ throw new Error(`Unsupported agents schema version ${String(config.schemaVersion)}. Expected ${String(AGENTS_SCHEMA_VERSION)}.`);
82
+ }
83
+ config.instructions = {
84
+ path: config.instructions?.path?.trim() || 'AGENTS.md'
85
+ };
86
+ config.integrations = {
87
+ enabled: Array.isArray(config.integrations?.enabled)
88
+ ? [...new Set(config.integrations.enabled)]
89
+ : [],
90
+ options: {
91
+ cursorAutoApprove: config.integrations?.options?.cursorAutoApprove !== false,
92
+ antigravityGlobalSync: config.integrations?.options?.antigravityGlobalSync === true
93
+ }
94
+ };
95
+ config.mcp = {
96
+ servers: typeof config.mcp?.servers === 'object' && config.mcp?.servers !== null
97
+ ? config.mcp.servers
98
+ : {}
99
+ };
100
+ config.workspace = {
101
+ vscode: {
102
+ hideGenerated: config.workspace?.vscode?.hideGenerated !== false,
103
+ hiddenPaths: Array.isArray(config.workspace?.vscode?.hiddenPaths) && config.workspace.vscode.hiddenPaths.length > 0
104
+ ? [...new Set(config.workspace.vscode.hiddenPaths)]
105
+ : [...DEFAULT_VSCODE_HIDDEN_PATHS]
106
+ }
107
+ };
108
+ if (config.lastSync !== null && typeof config.lastSync !== 'string') {
109
+ config.lastSync = null;
110
+ }
111
+ return config;
112
+ }
113
+ export async function saveAgentsConfig(projectRoot, config) {
114
+ const paths = getProjectPaths(projectRoot);
115
+ await ensureDir(path.dirname(paths.agentsConfig));
116
+ await writeJsonAtomic(paths.agentsConfig, config);
117
+ }
118
+ // Compatibility aliases for existing command imports.
119
+ export const loadProjectConfig = loadAgentsConfig;
120
+ export const saveProjectConfig = saveAgentsConfig;
121
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export type CursorServerState = 'ready' | 'needs-approval' | 'disabled' | 'error' | 'unknown';
2
+ export interface CursorMcpListResult {
3
+ ok: boolean;
4
+ statuses: Record<string, CursorServerState>;
5
+ stderr: string;
6
+ }
7
+ export declare function sanitizeTerminalOutput(input: string): string;
8
+ export declare function parseCursorMcpStatuses(output: string): Record<string, CursorServerState>;
9
+ export declare function listCursorMcpStatuses(projectRoot: string, timeoutMs?: number): CursorMcpListResult;
@@ -0,0 +1,60 @@
1
+ import { runCommand } from './shell.js';
2
+ const ANSI_PATTERN = /\u001B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~]|\][^\u0007]*(?:\u0007|\u001B\\))/g;
3
+ export function sanitizeTerminalOutput(input) {
4
+ return input
5
+ .replace(ANSI_PATTERN, '')
6
+ .replace(/\r/g, '\n');
7
+ }
8
+ export function parseCursorMcpStatuses(output) {
9
+ const statuses = {};
10
+ const lines = sanitizeTerminalOutput(output)
11
+ .split('\n')
12
+ .map((line) => line.trim())
13
+ .filter(Boolean);
14
+ for (const line of lines) {
15
+ const match = line.match(/^([a-zA-Z0-9._:-]+):\s*(.+)$/);
16
+ if (!match)
17
+ continue;
18
+ const name = match[1];
19
+ const statusText = match[2].toLowerCase();
20
+ if (!name)
21
+ continue;
22
+ if (statusText.includes('ready')) {
23
+ statuses[name] = 'ready';
24
+ continue;
25
+ }
26
+ if (statusText.includes('needs approval') || statusText.includes('not loaded')) {
27
+ statuses[name] = 'needs-approval';
28
+ continue;
29
+ }
30
+ if (statusText.includes('disabled')) {
31
+ statuses[name] = 'disabled';
32
+ continue;
33
+ }
34
+ if (statusText.includes('error')
35
+ || statusText.includes('failed')
36
+ || statusText.includes('disconnected')
37
+ || statusText.includes('connection failed')) {
38
+ statuses[name] = 'error';
39
+ continue;
40
+ }
41
+ statuses[name] = 'unknown';
42
+ }
43
+ return statuses;
44
+ }
45
+ export function listCursorMcpStatuses(projectRoot, timeoutMs) {
46
+ const result = runCommand('cursor-agent', ['mcp', 'list'], projectRoot, timeoutMs);
47
+ if (!result.ok) {
48
+ return {
49
+ ok: false,
50
+ statuses: {},
51
+ stderr: result.stderr
52
+ };
53
+ }
54
+ return {
55
+ ok: true,
56
+ statuses: parseCursorMcpStatuses(`${result.stdout}\n${result.stderr}`),
57
+ stderr: result.stderr
58
+ };
59
+ }
60
+ //# sourceMappingURL=cursorCli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursorCli.js","sourceRoot":"","sources":["../../src/core/cursorCli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAUvC,MAAM,YAAY,GAAG,0EAA0E,CAAA;AAE/F,MAAM,UAAU,sBAAsB,CAAC,KAAa;IAClD,OAAO,KAAK;SACT,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC;SACzB,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;AACzB,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,MAAc;IACnD,MAAM,QAAQ,GAAsC,EAAE,CAAA;IACtD,MAAM,KAAK,GAAG,sBAAsB,CAAC,MAAM,CAAC;SACzC,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,OAAO,CAAC,CAAA;IAElB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAA;QACxD,IAAI,CAAC,KAAK;YAAE,SAAQ;QAEpB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;QACrB,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAA;QACzC,IAAI,CAAC,IAAI;YAAE,SAAQ;QAEnB,IAAI,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACjC,QAAQ,CAAC,IAAI,CAAC,GAAG,OAAO,CAAA;YACxB,SAAQ;QACV,CAAC;QACD,IAAI,UAAU,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YAC/E,QAAQ,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAA;YACjC,SAAQ;QACV,CAAC;QACD,IAAI,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YACpC,QAAQ,CAAC,IAAI,CAAC,GAAG,UAAU,CAAA;YAC3B,SAAQ;QACV,CAAC;QACD,IACE,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC;eACzB,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC;eAC7B,UAAU,CAAC,QAAQ,CAAC,cAAc,CAAC;eACnC,UAAU,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAC3C,CAAC;YACD,QAAQ,CAAC,IAAI,CAAC,GAAG,OAAO,CAAA;YACxB,SAAQ;QACV,CAAC;QAED,QAAQ,CAAC,IAAI,CAAC,GAAG,SAAS,CAAA;IAC5B,CAAC;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,WAAmB,EAAE,SAAkB;IAC3E,MAAM,MAAM,GAAG,UAAU,CAAC,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,WAAW,EAAE,SAAS,CAAC,CAAA;IAClF,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,OAAO;YACL,EAAE,EAAE,KAAK;YACT,QAAQ,EAAE,EAAE;YACZ,MAAM,EAAE,MAAM,CAAC,MAAM;SACtB,CAAA;IACH,CAAC;IAED,OAAO;QACL,EAAE,EAAE,IAAI;QACR,QAAQ,EAAE,sBAAsB,CAAC,GAAG,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC;QACtE,MAAM,EAAE,MAAM,CAAC,MAAM;KACtB,CAAA;AACH,CAAC"}
@@ -0,0 +1,11 @@
1
+ export declare function pathExists(filePath: string): Promise<boolean>;
2
+ export declare function ensureDir(dirPath: string): Promise<void>;
3
+ export declare function readJson<T>(filePath: string): Promise<T>;
4
+ export declare function writeJsonAtomic(filePath: string, value: unknown): Promise<void>;
5
+ export declare function writeTextAtomic(filePath: string, content: string): Promise<void>;
6
+ export declare function removeIfExists(filePath: string): Promise<void>;
7
+ export declare function isDirectory(dirPath: string): Promise<boolean>;
8
+ export declare function isSymlink(filePath: string): Promise<boolean>;
9
+ export declare function readTextOrEmpty(filePath: string): Promise<string>;
10
+ export declare function listDirNames(dirPath: string): Promise<string[]>;
11
+ export declare function copyDir(fromDir: string, toDir: string): Promise<void>;
@@ -0,0 +1,76 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { access, cp, lstat, mkdir, readFile, readdir, rename, rm, stat, writeFile } from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ export async function pathExists(filePath) {
5
+ try {
6
+ await access(filePath);
7
+ return true;
8
+ }
9
+ catch {
10
+ try {
11
+ await lstat(filePath);
12
+ return true;
13
+ }
14
+ catch {
15
+ return false;
16
+ }
17
+ }
18
+ }
19
+ export async function ensureDir(dirPath) {
20
+ await mkdir(dirPath, { recursive: true });
21
+ }
22
+ export async function readJson(filePath) {
23
+ const raw = await readFile(filePath, 'utf8');
24
+ try {
25
+ return JSON.parse(raw);
26
+ }
27
+ catch (error) {
28
+ throw new Error(`Failed to parse JSON from ${filePath}: ${error instanceof Error ? error.message : String(error)}`);
29
+ }
30
+ }
31
+ export async function writeJsonAtomic(filePath, value) {
32
+ await writeTextAtomic(filePath, `${JSON.stringify(value, null, 2)}\n`);
33
+ }
34
+ export async function writeTextAtomic(filePath, content) {
35
+ await ensureDir(path.dirname(filePath));
36
+ const tmpPath = `${filePath}.${randomUUID()}.tmp`;
37
+ await writeFile(tmpPath, content, 'utf8');
38
+ await rename(tmpPath, filePath);
39
+ }
40
+ export async function removeIfExists(filePath) {
41
+ if (await pathExists(filePath)) {
42
+ await rm(filePath, { recursive: true, force: true });
43
+ }
44
+ }
45
+ export async function isDirectory(dirPath) {
46
+ try {
47
+ return (await stat(dirPath)).isDirectory();
48
+ }
49
+ catch {
50
+ return false;
51
+ }
52
+ }
53
+ export async function isSymlink(filePath) {
54
+ try {
55
+ return (await lstat(filePath)).isSymbolicLink();
56
+ }
57
+ catch {
58
+ return false;
59
+ }
60
+ }
61
+ export async function readTextOrEmpty(filePath) {
62
+ if (!(await pathExists(filePath)))
63
+ return '';
64
+ return readFile(filePath, 'utf8');
65
+ }
66
+ export async function listDirNames(dirPath) {
67
+ if (!(await isDirectory(dirPath)))
68
+ return [];
69
+ const entries = await readdir(dirPath, { withFileTypes: true });
70
+ return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name);
71
+ }
72
+ export async function copyDir(fromDir, toDir) {
73
+ await ensureDir(path.dirname(toDir));
74
+ await cp(fromDir, toDir, { recursive: true, force: true });
75
+ }
76
+ //# sourceMappingURL=fs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs.js","sourceRoot":"","sources":["../../src/core/fs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { SyncMode } from '../types.js';
2
+ export declare function ensureProjectGitignore(projectRoot: string, syncMode: SyncMode): Promise<boolean>;
3
+ export declare function cleanupManagedGitignore(projectRoot: string): Promise<boolean>;
@@ -0,0 +1,54 @@
1
+ import path from 'node:path';
2
+ import { readFile } from 'node:fs/promises';
3
+ import { pathExists, removeIfExists, writeTextAtomic } from './fs.js';
4
+ const BASE_MANAGED_ENTRIES = ['.agents/local.json', '.agents/generated/'];
5
+ const SOURCE_ONLY_ENTRIES = [
6
+ '.codex/',
7
+ '.gemini/',
8
+ '.vscode/mcp.json',
9
+ '.claude/skills',
10
+ '.cursor/',
11
+ '.antigravity/'
12
+ ];
13
+ export async function ensureProjectGitignore(projectRoot, syncMode) {
14
+ const gitignorePath = path.join(projectRoot, '.gitignore');
15
+ const exists = await pathExists(gitignorePath);
16
+ const content = exists ? await readFile(gitignorePath, 'utf8') : '';
17
+ const lines = content.split(/\r?\n/).filter(Boolean);
18
+ const required = syncMode === 'source-only' ? [...BASE_MANAGED_ENTRIES, ...SOURCE_ONLY_ENTRIES] : [...BASE_MANAGED_ENTRIES];
19
+ let changed = false;
20
+ for (const entry of required) {
21
+ if (lines.includes(entry))
22
+ continue;
23
+ lines.push(entry);
24
+ changed = true;
25
+ }
26
+ if (!changed)
27
+ return false;
28
+ await writeTextAtomic(gitignorePath, `${lines.join('\n')}\n`);
29
+ return true;
30
+ }
31
+ export async function cleanupManagedGitignore(projectRoot) {
32
+ const gitignorePath = path.join(projectRoot, '.gitignore');
33
+ if (!(await pathExists(gitignorePath)))
34
+ return false;
35
+ const content = await readFile(gitignorePath, 'utf8');
36
+ const lines = content.split(/\r?\n/);
37
+ const managed = new Set([...BASE_MANAGED_ENTRIES, ...SOURCE_ONLY_ENTRIES]);
38
+ const filtered = lines.filter((line) => !managed.has(line.trim()));
39
+ if (filtered.join('\n') === lines.join('\n')) {
40
+ return false;
41
+ }
42
+ const normalized = filtered.filter((line, idx, arr) => {
43
+ if (idx === arr.length - 1 && line === '')
44
+ return false;
45
+ return true;
46
+ });
47
+ if (normalized.length === 0) {
48
+ await removeIfExists(gitignorePath);
49
+ return true;
50
+ }
51
+ await writeTextAtomic(gitignorePath, `${normalized.join('\n')}\n`);
52
+ return true;
53
+ }
54
+ //# sourceMappingURL=gitignore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gitignore.js","sourceRoot":"","sources":["../../src/core/gitignore.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAE3C,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAErE,MAAM,oBAAoB,GAAG,CAAC,oBAAoB,EAAE,oBAAoB,CAAC,CAAA;AACzE,MAAM,mBAAmB,GAAG;IAC1B,SAAS;IACT,UAAU;IACV,kBAAkB;IAClB,gBAAgB;IAChB,UAAU;IACV,eAAe;CAChB,CAAA;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,WAAmB,EAAE,QAAkB;IAClF,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,CAAA;IAC1D,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,aAAa,CAAC,CAAA;IAC9C,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IACnE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IAEpD,MAAM,QAAQ,GACZ,QAAQ,KAAK,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,oBAAoB,EAAE,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,oBAAoB,CAAC,CAAA;IAE5G,IAAI,OAAO,GAAG,KAAK,CAAA;IACnB,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QAC7B,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,SAAQ;QACnC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACjB,OAAO,GAAG,IAAI,CAAA;IAChB,CAAC;IAED,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAA;IAC1B,MAAM,eAAe,CAAC,aAAa,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC7D,OAAO,IAAI,CAAA;AACb,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,WAAmB;IAC/D,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,CAAA;IAC1D,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,aAAa,CAAC,CAAC;QAAE,OAAO,KAAK,CAAA;IAEpD,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC,CAAA;IACrD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IAEpC,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,oBAAoB,EAAE,GAAG,mBAAmB,CAAC,CAAC,CAAA;IAC1E,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;IAElE,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7C,OAAO,KAAK,CAAA;IACd,CAAC;IAED,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QACpD,IAAI,GAAG,KAAK,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,KAAK,EAAE;YAAE,OAAO,KAAK,CAAA;QACvD,OAAO,IAAI,CAAA;IACb,CAAC,CAAC,CAAA;IAEF,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,cAAc,CAAC,aAAa,CAAC,CAAA;QACnC,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM,eAAe,CAAC,aAAa,EAAE,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAClE,OAAO,IAAI,CAAA;AACb,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { LocalOverridesFile, McpServerDefinition, ResolvedRegistry } from '../types.js';
2
+ export declare function loadLocalOverrides(projectRoot: string): Promise<LocalOverridesFile>;
3
+ export declare function loadResolvedRegistry(projectRoot: string): Promise<ResolvedRegistry>;
4
+ export declare function resolveFromConfigAndLocal(input: {
5
+ projectRoot: string;
6
+ servers: Record<string, McpServerDefinition>;
7
+ local: LocalOverridesFile;
8
+ }): ResolvedRegistry;