teamcast 0.9.2 → 0.9.3-a
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/dist/application/team.d.ts +0 -1
- package/dist/application/team.d.ts.map +1 -1
- package/dist/application/team.js +74 -6
- package/dist/application/team.js.map +1 -1
- package/dist/application/validate-team.d.ts +3 -2
- package/dist/application/validate-team.d.ts.map +1 -1
- package/dist/application/validate-team.js +12 -88
- package/dist/application/validate-team.js.map +1 -1
- package/dist/cli/diff.d.ts +2 -2
- package/dist/cli/diff.d.ts.map +1 -1
- package/dist/cli/diff.js +47 -50
- package/dist/cli/diff.js.map +1 -1
- package/dist/cli/errors.d.ts +7 -0
- package/dist/cli/errors.d.ts.map +1 -0
- package/dist/cli/errors.js +15 -0
- package/dist/cli/errors.js.map +1 -0
- package/dist/cli/explain.d.ts +2 -3
- package/dist/cli/explain.d.ts.map +1 -1
- package/dist/cli/explain.js +33 -37
- package/dist/cli/explain.js.map +1 -1
- package/dist/cli/generate.d.ts +4 -2
- package/dist/cli/generate.d.ts.map +1 -1
- package/dist/cli/generate.js +50 -54
- package/dist/cli/generate.js.map +1 -1
- package/dist/cli/import.d.ts +4 -2
- package/dist/cli/import.d.ts.map +1 -1
- package/dist/cli/import.js +92 -117
- package/dist/cli/import.js.map +1 -1
- package/dist/cli/index.js +8 -8
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init.d.ts +7 -2
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +37 -44
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/manage.d.ts +21 -2
- package/dist/cli/manage.d.ts.map +1 -1
- package/dist/cli/manage.js +158 -199
- package/dist/cli/manage.js.map +1 -1
- package/dist/cli/registrars/diff.d.ts +3 -0
- package/dist/cli/registrars/diff.d.ts.map +1 -0
- package/dist/cli/registrars/diff.js +10 -0
- package/dist/cli/registrars/diff.js.map +1 -0
- package/dist/cli/registrars/explain.d.ts +3 -0
- package/dist/cli/registrars/explain.d.ts.map +1 -0
- package/dist/cli/registrars/explain.js +10 -0
- package/dist/cli/registrars/explain.js.map +1 -0
- package/dist/cli/registrars/generate.d.ts +3 -0
- package/dist/cli/registrars/generate.d.ts.map +1 -0
- package/dist/cli/registrars/generate.js +11 -0
- package/dist/cli/registrars/generate.js.map +1 -0
- package/dist/cli/registrars/import.d.ts +3 -0
- package/dist/cli/registrars/import.d.ts.map +1 -0
- package/dist/cli/registrars/import.js +11 -0
- package/dist/cli/registrars/import.js.map +1 -0
- package/dist/cli/registrars/init.d.ts +3 -0
- package/dist/cli/registrars/init.d.ts.map +1 -0
- package/dist/cli/registrars/init.js +14 -0
- package/dist/cli/registrars/init.js.map +1 -0
- package/dist/cli/registrars/manage.d.ts +3 -0
- package/dist/cli/registrars/manage.d.ts.map +1 -0
- package/dist/cli/registrars/manage.js +54 -0
- package/dist/cli/registrars/manage.js.map +1 -0
- package/dist/cli/registrars/reset.d.ts +3 -0
- package/dist/cli/registrars/reset.d.ts.map +1 -0
- package/dist/cli/registrars/reset.js +19 -0
- package/dist/cli/registrars/reset.js.map +1 -0
- package/dist/cli/registrars/validate.d.ts +3 -0
- package/dist/cli/registrars/validate.d.ts.map +1 -0
- package/dist/cli/registrars/validate.js +12 -0
- package/dist/cli/registrars/validate.js.map +1 -0
- package/dist/cli/reset.d.ts +7 -2
- package/dist/cli/reset.d.ts.map +1 -1
- package/dist/cli/reset.js +60 -69
- package/dist/cli/reset.js.map +1 -1
- package/dist/cli/validate.d.ts +5 -2
- package/dist/cli/validate.d.ts.map +1 -1
- package/dist/cli/validate.js +33 -38
- package/dist/cli/validate.js.map +1 -1
- package/dist/generator/index.d.ts +0 -1
- package/dist/generator/index.d.ts.map +1 -1
- package/dist/generator/index.js +1 -3
- package/dist/generator/index.js.map +1 -1
- package/dist/importer/claude.d.ts +4 -0
- package/dist/importer/claude.d.ts.map +1 -0
- package/dist/importer/claude.js +51 -0
- package/dist/importer/claude.js.map +1 -0
- package/dist/importer/codex.d.ts +4 -0
- package/dist/importer/codex.d.ts.map +1 -0
- package/dist/importer/codex.js +50 -0
- package/dist/importer/codex.js.map +1 -0
- package/dist/importer/index.d.ts +8 -12
- package/dist/importer/index.d.ts.map +1 -1
- package/dist/importer/index.js +36 -509
- package/dist/importer/index.js.map +1 -1
- package/dist/importer/shared.d.ts +40 -0
- package/dist/importer/shared.d.ts.map +1 -0
- package/dist/importer/shared.js +373 -0
- package/dist/importer/shared.js.map +1 -0
- package/dist/importer/types.d.ts +16 -0
- package/dist/importer/types.d.ts.map +1 -0
- package/dist/importer/types.js +2 -0
- package/dist/importer/types.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -4
- package/dist/index.js.map +1 -1
- package/dist/manifest/defaults.d.ts.map +1 -1
- package/dist/manifest/defaults.js +76 -20
- package/dist/manifest/defaults.js.map +1 -1
- package/dist/manifest/normalize.d.ts.map +1 -1
- package/dist/manifest/normalize.js +9 -5
- package/dist/manifest/normalize.js.map +1 -1
- package/dist/manifest/targets.d.ts +11 -0
- package/dist/manifest/targets.d.ts.map +1 -0
- package/dist/manifest/targets.js +29 -0
- package/dist/manifest/targets.js.map +1 -0
- package/dist/manifest/types.d.ts +0 -2
- package/dist/manifest/types.d.ts.map +1 -1
- package/dist/manifest/types.js.map +1 -1
- package/dist/plugins/catalog.d.ts +10 -0
- package/dist/plugins/catalog.d.ts.map +1 -0
- package/dist/plugins/catalog.js +30 -0
- package/dist/plugins/catalog.js.map +1 -0
- package/dist/plugins/core/presets-plugin.d.ts +3 -0
- package/dist/plugins/core/presets-plugin.d.ts.map +1 -0
- package/dist/plugins/core/presets-plugin.js +10 -0
- package/dist/plugins/core/presets-plugin.js.map +1 -0
- package/dist/plugins/index.d.ts.map +1 -1
- package/dist/plugins/index.js +2 -1
- package/dist/plugins/index.js.map +1 -1
- package/dist/plugins/inject.d.ts +6 -2
- package/dist/plugins/inject.d.ts.map +1 -1
- package/dist/plugins/inject.js +41 -9
- package/dist/plugins/inject.js.map +1 -1
- package/dist/plugins/merge-policies.d.ts +1 -1
- package/dist/plugins/merge-policies.d.ts.map +1 -1
- package/dist/plugins/merge-policies.js +49 -15
- package/dist/plugins/merge-policies.js.map +1 -1
- package/dist/plugins/registry.d.ts +12 -6
- package/dist/plugins/registry.d.ts.map +1 -1
- package/dist/plugins/registry.js +34 -0
- package/dist/plugins/registry.js.map +1 -1
- package/dist/plugins/types.d.ts +8 -4
- package/dist/plugins/types.d.ts.map +1 -1
- package/dist/presets/index.d.ts +1 -0
- package/dist/presets/index.d.ts.map +1 -1
- package/dist/presets/index.js +62 -16
- package/dist/presets/index.js.map +1 -1
- package/dist/renderers/codex/skill-map.d.ts.map +1 -1
- package/dist/renderers/codex/skill-map.js.map +1 -1
- package/dist/renderers/registry.d.ts +1 -0
- package/dist/renderers/registry.d.ts.map +1 -1
- package/dist/renderers/registry.js +21 -0
- package/dist/renderers/registry.js.map +1 -1
- package/dist/team-templates/presets.d.ts.map +1 -1
- package/dist/team-templates/presets.js +9 -5
- package/dist/team-templates/presets.js.map +1 -1
- package/dist/team-templates/roles.d.ts.map +1 -1
- package/dist/team-templates/roles.js +0 -3
- package/dist/team-templates/roles.js.map +1 -1
- package/dist/utils/skill-prompt-options.d.ts +4 -0
- package/dist/utils/skill-prompt-options.d.ts.map +1 -0
- package/dist/utils/skill-prompt-options.js +12 -0
- package/dist/utils/skill-prompt-options.js.map +1 -0
- package/dist/validator/reporter.d.ts +2 -0
- package/dist/validator/reporter.d.ts.map +1 -1
- package/dist/validator/reporter.js +38 -30
- package/dist/validator/reporter.js.map +1 -1
- package/dist/wizard/index.d.ts.map +1 -1
- package/dist/wizard/index.js +7 -6
- package/dist/wizard/index.js.map +1 -1
- package/dist/wizard/steps/agent-customization.d.ts.map +1 -1
- package/dist/wizard/steps/agent-customization.js +4 -20
- package/dist/wizard/steps/agent-customization.js.map +1 -1
- package/dist/wizard/steps/team-selection.js +2 -2
- package/dist/wizard/steps/team-selection.js.map +1 -1
- package/package.json +2 -2
- package/schema/teamcast.schema.json +0 -6
- package/templates/presets/feature-team.yaml +9 -9
- package/templates/presets/research-and-build.yaml +9 -9
- package/templates/presets/secure-dev.yaml +20 -20
- package/templates/presets/solo-dev.yaml +8 -8
- package/dist/core/index.d.ts +0 -8
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/index.js +0 -8
- package/dist/core/index.js.map +0 -1
- package/dist/renderers/index.d.ts +0 -6
- package/dist/renderers/index.d.ts.map +0 -1
- package/dist/renderers/index.js +0 -9
- package/dist/renderers/index.js.map +0 -1
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { existsSync } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { createManifestForTarget } from '../manifest/normalize.js';
|
|
4
|
+
import { getTarget } from '../renderers/registry.js';
|
|
5
|
+
import { parseCodexAgentFile, parseCodexConfigEntries, } from './shared.js';
|
|
6
|
+
export function importFromCodexDir(cwd, projectName) {
|
|
7
|
+
const warnings = [];
|
|
8
|
+
const agents = {};
|
|
9
|
+
const targetContext = getTarget('codex');
|
|
10
|
+
const configPath = join(cwd, '.codex', 'config.toml');
|
|
11
|
+
if (!existsSync(configPath)) {
|
|
12
|
+
warnings.push({ file: configPath, message: 'No .codex/config.toml file found' });
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
const entries = parseCodexConfigEntries(configPath);
|
|
16
|
+
for (const entry of entries) {
|
|
17
|
+
const agentPath = join(cwd, '.codex', entry.configPath);
|
|
18
|
+
if (!existsSync(agentPath)) {
|
|
19
|
+
warnings.push({ file: agentPath, message: `Missing config for agent "${entry.name}"` });
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
const result = parseCodexAgentFile(cwd, entry, targetContext);
|
|
23
|
+
agents[result.name] = result.agent;
|
|
24
|
+
warnings.push(...result.warnings);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
if (Object.keys(agents).length === 0) {
|
|
28
|
+
warnings.push({ file: join(cwd, '.codex', 'agents'), message: 'No agent .toml files found in .codex/agents/' });
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
team: createManifestForTarget({
|
|
32
|
+
version: '2',
|
|
33
|
+
project: { name: projectName },
|
|
34
|
+
agents,
|
|
35
|
+
settings: {
|
|
36
|
+
generateDocs: true,
|
|
37
|
+
generateLocalSettings: true,
|
|
38
|
+
},
|
|
39
|
+
}, 'codex'),
|
|
40
|
+
warnings,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export const codexImportHandler = {
|
|
44
|
+
targetName: 'codex',
|
|
45
|
+
detect(cwd) {
|
|
46
|
+
return existsSync(join(cwd, '.codex'));
|
|
47
|
+
},
|
|
48
|
+
importFromDir: importFromCodexDir,
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=codex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/importer/codex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EACL,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,aAAa,CAAC;AAGrB,MAAM,UAAU,kBAAkB,CAAC,GAAW,EAAE,WAAmB;IACjE,MAAM,QAAQ,GAAoB,EAAE,CAAC;IACrC,MAAM,MAAM,GAA8B,EAAE,CAAC;IAC7C,MAAM,aAAa,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IACzC,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;IAEtD,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,kCAAkC,EAAE,CAAC,CAAC;IACnF,CAAC;SAAM,CAAC;QACN,MAAM,OAAO,GAAG,uBAAuB,CAAC,UAAU,CAAC,CAAC;QACpD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;YACxD,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,6BAA6B,KAAK,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;gBACxF,SAAS;YACX,CAAC;YAED,MAAM,MAAM,GAAG,mBAAmB,CAAC,GAAG,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC;YAC9D,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC;YACnC,QAAQ,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,8CAA8C,EAAE,CAAC,CAAC;IAClH,CAAC;IAED,OAAO;QACL,IAAI,EAAE,uBAAuB,CAAC;YAC5B,OAAO,EAAE,GAAG;YACZ,OAAO,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE;YAC9B,MAAM;YACN,QAAQ,EAAE;gBACR,YAAY,EAAE,IAAI;gBAClB,qBAAqB,EAAE,IAAI;aAC5B;SACF,EAAE,OAAO,CAAC;QACX,QAAQ;KACT,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAkB;IAC/C,UAAU,EAAE,OAAO;IACnB,MAAM,CAAC,GAAW;QAChB,OAAO,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC;IACzC,CAAC;IACD,aAAa,EAAE,kBAAkB;CAClC,CAAC"}
|
package/dist/importer/index.d.ts
CHANGED
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
export declare function importFromClaudeDir(cwd: string, projectName: string): ImportResult;
|
|
11
|
-
export declare function importFromCodexDir(cwd: string, projectName: string): ImportResult;
|
|
12
|
-
export {};
|
|
1
|
+
import type { ManifestTargetName } from '../manifest/targets.js';
|
|
2
|
+
import type { ImportHandler, ImportResult, ImportWarning } from './types.js';
|
|
3
|
+
export declare function registerImportHandler(handler: ImportHandler): void;
|
|
4
|
+
export declare function getImportHandler(targetName: ManifestTargetName): ImportHandler | undefined;
|
|
5
|
+
export declare function getImportHandlers(): ImportHandler[];
|
|
6
|
+
export declare function getDetectedImportHandlers(cwd: string): ImportHandler[];
|
|
7
|
+
export declare function importTargetFromDir(targetName: ManifestTargetName, cwd: string, projectName: string): ImportResult;
|
|
8
|
+
export type { ImportHandler, ImportResult, ImportWarning };
|
|
13
9
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/importer/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/importer/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAGjE,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAe7E,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAMlE;AAED,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,kBAAkB,GAAG,aAAa,GAAG,SAAS,CAG1F;AAED,wBAAgB,iBAAiB,IAAI,aAAa,EAAE,CAGnD;AAED,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,EAAE,CAEtE;AAED,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,kBAAkB,EAC9B,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,GAClB,YAAY,CAMd;AAED,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC"}
|
package/dist/importer/index.js
CHANGED
|
@@ -1,511 +1,38 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
'claude
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
return
|
|
27
|
-
}
|
|
28
|
-
function
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
nextBody = nextSection !== -1
|
|
38
|
-
? nextBody.slice(0, sectionIndex) + nextBody.slice(nextSection)
|
|
39
|
-
: nextBody.slice(0, sectionIndex);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
return nextBody.trim() || undefined;
|
|
43
|
-
}
|
|
44
|
-
function inferLegacyHandoffs(body) {
|
|
45
|
-
if (!body?.includes('## Delegation'))
|
|
46
|
-
return undefined;
|
|
47
|
-
const match = body.match(/## Delegation\s+You can delegate tasks to the following agents:\s+([a-z0-9,\- ]+)\./i);
|
|
48
|
-
if (!match)
|
|
49
|
-
return undefined;
|
|
50
|
-
const values = match[1]
|
|
51
|
-
.split(',')
|
|
52
|
-
.map((value) => value.trim())
|
|
53
|
-
.filter(Boolean);
|
|
54
|
-
return values.length > 0 ? values : undefined;
|
|
55
|
-
}
|
|
56
|
-
function resolveClaudeModel(modelValue) {
|
|
57
|
-
if (typeof modelValue !== 'string' || modelValue.length === 0)
|
|
58
|
-
return undefined;
|
|
59
|
-
if (modelValue === 'opus' || modelValue === 'sonnet' || modelValue === 'haiku') {
|
|
60
|
-
return modelValue;
|
|
61
|
-
}
|
|
62
|
-
return LEGACY_MODEL_ID_MAP[modelValue];
|
|
63
|
-
}
|
|
64
|
-
function isKnownTool(value, knownTools) {
|
|
65
|
-
return knownTools.includes(value);
|
|
66
|
-
}
|
|
67
|
-
function parseToolList(value, knownTools) {
|
|
68
|
-
const rawTools = Array.isArray(value)
|
|
69
|
-
? value.filter((item) => typeof item === 'string')
|
|
70
|
-
: typeof value === 'string'
|
|
71
|
-
? value.split(',').map((item) => item.trim()).filter(Boolean)
|
|
72
|
-
: [];
|
|
73
|
-
if (rawTools.length === 0)
|
|
74
|
-
return undefined;
|
|
75
|
-
const tools = [];
|
|
76
|
-
for (const raw of rawTools) {
|
|
77
|
-
const canonical = raw === 'Task' ? 'Agent' : raw;
|
|
78
|
-
if (isKnownTool(canonical, knownTools) && !tools.includes(canonical)) {
|
|
79
|
-
tools.push(canonical);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
return tools.length > 0 ? tools : undefined;
|
|
83
|
-
}
|
|
84
|
-
function parseSkillList(value) {
|
|
85
|
-
if (!Array.isArray(value))
|
|
86
|
-
return undefined;
|
|
87
|
-
const skills = value.filter((item) => typeof item === 'string' && item.length > 0);
|
|
88
|
-
return skills.length > 0 ? skills : undefined;
|
|
89
|
-
}
|
|
90
|
-
function parsePermissionMode(value) {
|
|
91
|
-
if (typeof value !== 'string')
|
|
92
|
-
return undefined;
|
|
93
|
-
const modes = ['default', 'acceptEdits', 'bypassPermissions', 'plan', 'dontAsk'];
|
|
94
|
-
return modes.includes(value) ? value : undefined;
|
|
95
|
-
}
|
|
96
|
-
function parseMcpServers(value) {
|
|
97
|
-
if (!Array.isArray(value))
|
|
98
|
-
return undefined;
|
|
99
|
-
const servers = value
|
|
100
|
-
.filter((item) => typeof item === 'object' && item !== null)
|
|
101
|
-
.map((item) => ({
|
|
102
|
-
name: typeof item.name === 'string' ? item.name : '',
|
|
103
|
-
url: typeof item.url === 'string' ? item.url : '',
|
|
104
|
-
}))
|
|
105
|
-
.filter((item) => item.name.length > 0 && item.url.length > 0);
|
|
106
|
-
return servers.length > 0 ? servers : undefined;
|
|
107
|
-
}
|
|
108
|
-
function normalizeLineEndings(value) {
|
|
109
|
-
return value.replace(/\r\n/g, '\n');
|
|
110
|
-
}
|
|
111
|
-
function escapeRegExp(value) {
|
|
112
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
113
|
-
}
|
|
114
|
-
function extractTomlString(content, key) {
|
|
115
|
-
const match = content.match(new RegExp(`^${escapeRegExp(key)}\\s*=\\s*"((?:\\\\.|[^"])*)"`, 'm'));
|
|
116
|
-
if (!match)
|
|
117
|
-
return undefined;
|
|
118
|
-
return match[1]
|
|
119
|
-
.replace(/\\"/g, '"')
|
|
120
|
-
.replace(/\\\\/g, '\\');
|
|
121
|
-
}
|
|
122
|
-
function extractTomlMultiline(content, key) {
|
|
123
|
-
const match = content.match(new RegExp(`${escapeRegExp(key)}\\s*=\\s*"""\\n([\\s\\S]*?)\\n"""`));
|
|
124
|
-
return match ? normalizeLineEndings(match[1]).trim() : undefined;
|
|
125
|
-
}
|
|
126
|
-
function extractMarkdownSection(content, heading) {
|
|
127
|
-
const normalized = normalizeLineEndings(content);
|
|
128
|
-
const match = normalized.match(new RegExp(`## ${escapeRegExp(heading)}\\n\\n([\\s\\S]*?)(?=\\n## |$)`));
|
|
129
|
-
return match?.[1]?.trim() || undefined;
|
|
130
|
-
}
|
|
131
|
-
function parseCommaList(value) {
|
|
132
|
-
if (!value)
|
|
133
|
-
return undefined;
|
|
134
|
-
const items = value
|
|
135
|
-
.split(',')
|
|
136
|
-
.map((entry) => entry.trim().replace(/\.$/, ''))
|
|
137
|
-
.filter(Boolean);
|
|
138
|
-
return items.length > 0 ? items : undefined;
|
|
139
|
-
}
|
|
140
|
-
function stripCodexGeneratedSections(body) {
|
|
141
|
-
if (!body)
|
|
142
|
-
return undefined;
|
|
143
|
-
let nextBody = normalizeLineEndings(body);
|
|
144
|
-
if (nextBody.startsWith('You are ')) {
|
|
145
|
-
const firstBreak = nextBody.indexOf('\n\n');
|
|
146
|
-
nextBody = firstBreak === -1 ? '' : nextBody.slice(firstBreak + 2);
|
|
147
|
-
}
|
|
148
|
-
for (const section of ['## Delegation', '## Allowed Tool Intents', '## Restricted Tool Intents', '## Skill Docs']) {
|
|
149
|
-
const sectionIndex = nextBody.indexOf(section);
|
|
150
|
-
if (sectionIndex !== -1) {
|
|
151
|
-
const nextSection = nextBody.indexOf('\n## ', sectionIndex + section.length);
|
|
152
|
-
nextBody = nextSection !== -1
|
|
153
|
-
? nextBody.slice(0, sectionIndex) + nextBody.slice(nextSection)
|
|
154
|
-
: nextBody.slice(0, sectionIndex);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
return nextBody.trim() || undefined;
|
|
158
|
-
}
|
|
159
|
-
function parseCodexReasoningEffort(value) {
|
|
160
|
-
if (!value)
|
|
161
|
-
return undefined;
|
|
162
|
-
if (value === 'low' || value === 'medium' || value === 'high' || value === 'xhigh') {
|
|
163
|
-
return value;
|
|
164
|
-
}
|
|
165
|
-
return undefined;
|
|
166
|
-
}
|
|
167
|
-
function parseAgentFile(filePath, targetContext) {
|
|
168
|
-
const warnings = [];
|
|
169
|
-
const content = readFileSync(filePath, 'utf-8');
|
|
170
|
-
const fields = parseFrontmatter(content);
|
|
171
|
-
const fileName = basename(filePath, '.md');
|
|
172
|
-
const name = typeof fields.name === 'string' && fields.name.length > 0 ? fields.name : fileName;
|
|
173
|
-
const model = resolveClaudeModel(fields.model);
|
|
174
|
-
const rawTools = parseToolList(fields.tools, targetContext.knownTools);
|
|
175
|
-
const tools = rawTools
|
|
176
|
-
? (() => {
|
|
177
|
-
const reverseMap = targetContext.reverseMapTools;
|
|
178
|
-
if (reverseMap) {
|
|
179
|
-
const { skills, remainingTools } = reverseMap(rawTools);
|
|
180
|
-
return [...skills, ...remainingTools];
|
|
181
|
-
}
|
|
182
|
-
return rawTools;
|
|
183
|
-
})()
|
|
184
|
-
: undefined;
|
|
185
|
-
const disallowedTools = parseToolList(fields.disallowedTools, targetContext.knownTools);
|
|
186
|
-
const permissionMode = parsePermissionMode(fields.permissionMode);
|
|
187
|
-
const maxTurns = typeof fields.maxTurns === 'number' ? fields.maxTurns : undefined;
|
|
188
|
-
const background = typeof fields.background === 'boolean' ? fields.background : undefined;
|
|
189
|
-
const skillDocs = parseSkillList(fields.skills);
|
|
190
|
-
const mcpServers = parseMcpServers(fields.mcpServers);
|
|
191
|
-
if (fields.model && !model) {
|
|
192
|
-
warnings.push({ file: filePath, message: `Unknown model "${String(fields.model)}", skipping model field` });
|
|
193
|
-
}
|
|
194
|
-
if (fields.permissionMode && !permissionMode) {
|
|
195
|
-
warnings.push({
|
|
196
|
-
file: filePath,
|
|
197
|
-
message: `Unknown permissionMode "${String(fields.permissionMode)}", skipping`,
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
|
-
const originalBody = extractBody(content);
|
|
201
|
-
const instructions = stripLegacyGeneratedSections(originalBody);
|
|
202
|
-
const legacyHandoffs = inferLegacyHandoffs(originalBody);
|
|
203
|
-
return {
|
|
204
|
-
name,
|
|
205
|
-
agent: {
|
|
206
|
-
id: name,
|
|
207
|
-
description: typeof fields.description === 'string' && fields.description.length > 0
|
|
208
|
-
? fields.description
|
|
209
|
-
: `Imported from ${fileName}.md`,
|
|
210
|
-
runtime: {
|
|
211
|
-
model,
|
|
212
|
-
tools,
|
|
213
|
-
disallowedTools,
|
|
214
|
-
permissionMode,
|
|
215
|
-
maxTurns,
|
|
216
|
-
skillDocs,
|
|
217
|
-
mcpServers,
|
|
218
|
-
background,
|
|
219
|
-
},
|
|
220
|
-
instructions: instructions
|
|
221
|
-
? [{ kind: 'behavior', content: instructions }]
|
|
222
|
-
: [],
|
|
223
|
-
metadata: legacyHandoffs?.length ? { handoffs: legacyHandoffs } : undefined,
|
|
224
|
-
},
|
|
225
|
-
warnings,
|
|
226
|
-
};
|
|
227
|
-
}
|
|
228
|
-
function parseSettingsJson(filePath) {
|
|
229
|
-
const warnings = [];
|
|
230
|
-
const content = readFileSync(filePath, 'utf-8');
|
|
231
|
-
let settings;
|
|
232
|
-
try {
|
|
233
|
-
settings = JSON.parse(content);
|
|
234
|
-
}
|
|
235
|
-
catch {
|
|
236
|
-
warnings.push({ file: filePath, message: 'Failed to parse settings.json' });
|
|
237
|
-
return { policies: {}, warnings };
|
|
238
|
-
}
|
|
239
|
-
const policies = {};
|
|
240
|
-
const perms = typeof settings.permissions === 'object' && settings.permissions !== null
|
|
241
|
-
? settings.permissions
|
|
242
|
-
: undefined;
|
|
243
|
-
if (perms) {
|
|
244
|
-
const allow = Array.isArray(perms.allow) ? perms.allow : undefined;
|
|
245
|
-
const ask = Array.isArray(perms.ask) ? perms.ask : undefined;
|
|
246
|
-
const deny = Array.isArray(perms.deny) ? perms.deny : undefined;
|
|
247
|
-
policies.permissions = {};
|
|
248
|
-
if (allow || ask || deny) {
|
|
249
|
-
policies.permissions.rules = {};
|
|
250
|
-
if (allow)
|
|
251
|
-
policies.permissions.rules.allow = allow;
|
|
252
|
-
if (ask)
|
|
253
|
-
policies.permissions.rules.ask = ask;
|
|
254
|
-
if (deny)
|
|
255
|
-
policies.permissions.rules.deny = deny;
|
|
256
|
-
}
|
|
257
|
-
if (perms.defaultMode && typeof perms.defaultMode === 'string') {
|
|
258
|
-
policies.permissions.defaultMode = perms.defaultMode;
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
const sandbox = typeof settings.sandbox === 'object' && settings.sandbox !== null
|
|
262
|
-
? settings.sandbox
|
|
263
|
-
: undefined;
|
|
264
|
-
if (sandbox) {
|
|
265
|
-
policies.sandbox = {};
|
|
266
|
-
if (typeof sandbox.enabled === 'boolean')
|
|
267
|
-
policies.sandbox.enabled = sandbox.enabled;
|
|
268
|
-
if (typeof sandbox.autoAllowBashIfSandboxed === 'boolean') {
|
|
269
|
-
policies.sandbox.autoAllowBash = sandbox.autoAllowBashIfSandboxed;
|
|
270
|
-
}
|
|
271
|
-
if (Array.isArray(sandbox.excludedCommands)) {
|
|
272
|
-
policies.sandbox.excludedCommands = sandbox.excludedCommands;
|
|
273
|
-
}
|
|
274
|
-
const network = typeof sandbox.network === 'object' && sandbox.network !== null
|
|
275
|
-
? sandbox.network
|
|
276
|
-
: undefined;
|
|
277
|
-
if (network) {
|
|
278
|
-
policies.sandbox.network = {};
|
|
279
|
-
if (Array.isArray(network.allowUnixSockets)) {
|
|
280
|
-
policies.sandbox.network.allowUnixSockets = network.allowUnixSockets;
|
|
281
|
-
}
|
|
282
|
-
if (typeof network.allowLocalBinding === 'boolean') {
|
|
283
|
-
policies.sandbox.network.allowLocalBinding = network.allowLocalBinding;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
const hooks = typeof settings.hooks === 'object' && settings.hooks !== null
|
|
288
|
-
? settings.hooks
|
|
289
|
-
: undefined;
|
|
290
|
-
if (hooks) {
|
|
291
|
-
const parseHookEntries = (entries) => entries
|
|
292
|
-
.filter((entry) => typeof entry === 'object' && entry !== null)
|
|
293
|
-
.map((entry) => ({
|
|
294
|
-
matcher: String(entry.matcher ?? ''),
|
|
295
|
-
command: Array.isArray(entry.hooks)
|
|
296
|
-
? String(entry.hooks[0]?.command ?? '')
|
|
297
|
-
: '',
|
|
298
|
-
}))
|
|
299
|
-
.filter((entry) => entry.matcher && entry.command);
|
|
300
|
-
policies.hooks = {};
|
|
301
|
-
if (Array.isArray(hooks.PreToolUse)) {
|
|
302
|
-
policies.hooks.preToolUse = parseHookEntries(hooks.PreToolUse);
|
|
303
|
-
}
|
|
304
|
-
if (Array.isArray(hooks.PostToolUse)) {
|
|
305
|
-
policies.hooks.postToolUse = parseHookEntries(hooks.PostToolUse);
|
|
306
|
-
}
|
|
307
|
-
if (Array.isArray(hooks.Notification)) {
|
|
308
|
-
policies.hooks.notification = parseHookEntries(hooks.Notification);
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
return { policies, warnings };
|
|
312
|
-
}
|
|
313
|
-
export function importFromClaudeDir(cwd, projectName) {
|
|
314
|
-
const warnings = [];
|
|
315
|
-
const agents = {};
|
|
316
|
-
const claudeTarget = createClaudeTarget();
|
|
317
|
-
const agentsDir = join(cwd, '.claude', 'agents');
|
|
318
|
-
if (existsSync(agentsDir)) {
|
|
319
|
-
const files = readdirSync(agentsDir).filter((file) => file.endsWith('.md'));
|
|
320
|
-
for (const file of files) {
|
|
321
|
-
const filePath = join(agentsDir, file);
|
|
322
|
-
const result = parseAgentFile(filePath, claudeTarget);
|
|
323
|
-
agents[result.name] = result.agent;
|
|
324
|
-
warnings.push(...result.warnings);
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
if (Object.keys(agents).length === 0) {
|
|
328
|
-
warnings.push({ file: agentsDir, message: 'No agent .md files found in .claude/agents/' });
|
|
329
|
-
}
|
|
330
|
-
let policies;
|
|
331
|
-
const settingsPath = join(cwd, '.claude', 'settings.json');
|
|
332
|
-
if (existsSync(settingsPath)) {
|
|
333
|
-
const result = parseSettingsJson(settingsPath);
|
|
334
|
-
policies = result.policies;
|
|
335
|
-
warnings.push(...result.warnings);
|
|
336
|
-
}
|
|
337
|
-
const agentConfigs = {};
|
|
338
|
-
for (const [id, coreAgent] of Object.entries(agents)) {
|
|
339
|
-
agentConfigs[id] = {
|
|
340
|
-
description: coreAgent.description,
|
|
341
|
-
model: coreAgent.runtime.model,
|
|
342
|
-
reasoning_effort: coreAgent.runtime.reasoningEffort,
|
|
343
|
-
tools: coreAgent.runtime.tools,
|
|
344
|
-
disallowed_tools: coreAgent.runtime.disallowedTools,
|
|
345
|
-
permission_mode: coreAgent.runtime.permissionMode,
|
|
346
|
-
skills: coreAgent.runtime.skillDocs,
|
|
347
|
-
max_turns: coreAgent.runtime.maxTurns,
|
|
348
|
-
mcp_servers: coreAgent.runtime.mcpServers,
|
|
349
|
-
background: coreAgent.runtime.background,
|
|
350
|
-
instruction_blocks: coreAgent.instructions,
|
|
351
|
-
forge: coreAgent.metadata,
|
|
352
|
-
};
|
|
353
|
-
}
|
|
354
|
-
return {
|
|
355
|
-
team: {
|
|
356
|
-
version: '2',
|
|
357
|
-
project: { name: projectName },
|
|
358
|
-
claude: {
|
|
359
|
-
agents: agentConfigs,
|
|
360
|
-
policies: policies ? {
|
|
361
|
-
permissions: policies.permissions ? {
|
|
362
|
-
rules: policies.permissions.rules ? {
|
|
363
|
-
allow: policies.permissions.rules.allow,
|
|
364
|
-
ask: policies.permissions.rules.ask,
|
|
365
|
-
deny: policies.permissions.rules.deny,
|
|
366
|
-
} : undefined,
|
|
367
|
-
default_mode: policies.permissions.defaultMode,
|
|
368
|
-
} : undefined,
|
|
369
|
-
sandbox: policies.sandbox ? {
|
|
370
|
-
enabled: policies.sandbox.enabled,
|
|
371
|
-
auto_allow_bash: policies.sandbox.autoAllowBash,
|
|
372
|
-
excluded_commands: policies.sandbox.excludedCommands,
|
|
373
|
-
network: policies.sandbox.network ? {
|
|
374
|
-
allow_unix_sockets: policies.sandbox.network.allowUnixSockets,
|
|
375
|
-
allow_local_binding: policies.sandbox.network.allowLocalBinding,
|
|
376
|
-
} : undefined,
|
|
377
|
-
} : undefined,
|
|
378
|
-
hooks: policies.hooks ? {
|
|
379
|
-
pre_tool_use: policies.hooks.preToolUse,
|
|
380
|
-
post_tool_use: policies.hooks.postToolUse,
|
|
381
|
-
notification: policies.hooks.notification,
|
|
382
|
-
} : undefined,
|
|
383
|
-
} : undefined,
|
|
384
|
-
settings: {
|
|
385
|
-
generate_docs: true,
|
|
386
|
-
generate_local_settings: true,
|
|
387
|
-
},
|
|
388
|
-
},
|
|
389
|
-
},
|
|
390
|
-
warnings,
|
|
391
|
-
};
|
|
392
|
-
}
|
|
393
|
-
function parseCodexConfigEntries(filePath) {
|
|
394
|
-
const content = normalizeLineEndings(readFileSync(filePath, 'utf-8'));
|
|
395
|
-
const sectionRegex = /\[agents\.([^\]]+)\]\n([\s\S]*?)(?=\n\[agents\.|\s*$)/g;
|
|
396
|
-
const entries = [];
|
|
397
|
-
for (const match of content.matchAll(sectionRegex)) {
|
|
398
|
-
const name = match[1];
|
|
399
|
-
const block = match[2];
|
|
400
|
-
const description = extractTomlString(block, 'description');
|
|
401
|
-
const configPath = extractTomlString(block, 'config_file');
|
|
402
|
-
if (description && configPath) {
|
|
403
|
-
entries.push({ name, description, configPath });
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
return entries;
|
|
407
|
-
}
|
|
408
|
-
function parseCodexToolList(value, knownTools) {
|
|
409
|
-
const items = parseCommaList(value);
|
|
410
|
-
if (!items)
|
|
411
|
-
return undefined;
|
|
412
|
-
const tools = items.filter((item) => knownTools.includes(item));
|
|
413
|
-
return tools.length > 0 ? tools : undefined;
|
|
414
|
-
}
|
|
415
|
-
function parseCodexAgentFile(cwd, entry, targetContext) {
|
|
416
|
-
const warnings = [];
|
|
417
|
-
const filePath = join(cwd, '.codex', entry.configPath);
|
|
418
|
-
const content = normalizeLineEndings(readFileSync(filePath, 'utf-8'));
|
|
419
|
-
const developerInstructions = extractTomlMultiline(content, 'developer_instructions');
|
|
420
|
-
const delegation = extractMarkdownSection(developerInstructions ?? '', 'Delegation');
|
|
421
|
-
const allowedToolIntents = extractMarkdownSection(developerInstructions ?? '', 'Allowed Tool Intents');
|
|
422
|
-
const restrictedToolIntents = extractMarkdownSection(developerInstructions ?? '', 'Restricted Tool Intents');
|
|
423
|
-
const skillDocsSection = extractMarkdownSection(developerInstructions ?? '', 'Skill Docs');
|
|
424
|
-
const reasoningEffort = parseCodexReasoningEffort(extractTomlString(content, 'model_reasoning_effort'));
|
|
425
|
-
if (extractTomlString(content, 'model_reasoning_effort') && !reasoningEffort) {
|
|
426
|
-
warnings.push({
|
|
427
|
-
file: filePath,
|
|
428
|
-
message: `Unknown reasoning effort "${String(extractTomlString(content, 'model_reasoning_effort'))}", skipping`,
|
|
429
|
-
});
|
|
430
|
-
}
|
|
431
|
-
const handoffs = parseCommaList(delegation?.replace(/^You may delegate to:\s*/i, ''));
|
|
432
|
-
const tools = parseCodexToolList(allowedToolIntents, targetContext.knownTools);
|
|
433
|
-
const disallowedTools = parseCodexToolList(restrictedToolIntents?.replace(/^Avoid using:\s*/i, ''), targetContext.knownTools);
|
|
434
|
-
const skillDocs = parseCommaList(skillDocsSection?.replace(/^Follow these local skills when relevant:\s*/i, ''));
|
|
435
|
-
return {
|
|
436
|
-
name: entry.name,
|
|
437
|
-
agent: {
|
|
438
|
-
id: entry.name,
|
|
439
|
-
description: entry.description,
|
|
440
|
-
runtime: {
|
|
441
|
-
model: extractTomlString(content, 'model'),
|
|
442
|
-
reasoningEffort,
|
|
443
|
-
tools,
|
|
444
|
-
disallowedTools,
|
|
445
|
-
skillDocs,
|
|
446
|
-
},
|
|
447
|
-
instructions: stripCodexGeneratedSections(developerInstructions)
|
|
448
|
-
? [{ kind: 'behavior', content: stripCodexGeneratedSections(developerInstructions) }]
|
|
449
|
-
: [],
|
|
450
|
-
metadata: handoffs?.length ? { handoffs } : undefined,
|
|
451
|
-
},
|
|
452
|
-
warnings,
|
|
453
|
-
};
|
|
454
|
-
}
|
|
455
|
-
export function importFromCodexDir(cwd, projectName) {
|
|
456
|
-
const warnings = [];
|
|
457
|
-
const agents = {};
|
|
458
|
-
const codexTarget = createCodexTarget();
|
|
459
|
-
const configPath = join(cwd, '.codex', 'config.toml');
|
|
460
|
-
if (!existsSync(configPath)) {
|
|
461
|
-
warnings.push({ file: configPath, message: 'No .codex/config.toml file found' });
|
|
462
|
-
}
|
|
463
|
-
else {
|
|
464
|
-
const entries = parseCodexConfigEntries(configPath);
|
|
465
|
-
for (const entry of entries) {
|
|
466
|
-
const agentPath = join(cwd, '.codex', entry.configPath);
|
|
467
|
-
if (!existsSync(agentPath)) {
|
|
468
|
-
warnings.push({ file: agentPath, message: `Missing config for agent "${entry.name}"` });
|
|
469
|
-
continue;
|
|
470
|
-
}
|
|
471
|
-
const result = parseCodexAgentFile(cwd, entry, codexTarget);
|
|
472
|
-
agents[result.name] = result.agent;
|
|
473
|
-
warnings.push(...result.warnings);
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
if (Object.keys(agents).length === 0) {
|
|
477
|
-
warnings.push({ file: join(cwd, '.codex', 'agents'), message: 'No agent .toml files found in .codex/agents/' });
|
|
478
|
-
}
|
|
479
|
-
const agentConfigs = {};
|
|
480
|
-
for (const [id, coreAgent] of Object.entries(agents)) {
|
|
481
|
-
agentConfigs[id] = {
|
|
482
|
-
description: coreAgent.description,
|
|
483
|
-
model: coreAgent.runtime.model,
|
|
484
|
-
reasoning_effort: coreAgent.runtime.reasoningEffort,
|
|
485
|
-
tools: coreAgent.runtime.tools,
|
|
486
|
-
disallowed_tools: coreAgent.runtime.disallowedTools,
|
|
487
|
-
permission_mode: coreAgent.runtime.permissionMode,
|
|
488
|
-
skills: coreAgent.runtime.skillDocs,
|
|
489
|
-
max_turns: coreAgent.runtime.maxTurns,
|
|
490
|
-
mcp_servers: coreAgent.runtime.mcpServers,
|
|
491
|
-
background: coreAgent.runtime.background,
|
|
492
|
-
instruction_blocks: coreAgent.instructions,
|
|
493
|
-
forge: coreAgent.metadata,
|
|
494
|
-
};
|
|
495
|
-
}
|
|
496
|
-
return {
|
|
497
|
-
team: {
|
|
498
|
-
version: '2',
|
|
499
|
-
project: { name: projectName },
|
|
500
|
-
codex: {
|
|
501
|
-
agents: agentConfigs,
|
|
502
|
-
settings: {
|
|
503
|
-
generate_docs: true,
|
|
504
|
-
generate_local_settings: true,
|
|
505
|
-
},
|
|
506
|
-
},
|
|
507
|
-
},
|
|
508
|
-
warnings,
|
|
509
|
-
};
|
|
1
|
+
import { claudeImportHandler } from './claude.js';
|
|
2
|
+
import { codexImportHandler } from './codex.js';
|
|
3
|
+
const registry = new Map();
|
|
4
|
+
let builtinsRegistered = false;
|
|
5
|
+
function ensureBuiltinImportHandlersRegistered() {
|
|
6
|
+
if (builtinsRegistered) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
registry.set('claude', claudeImportHandler);
|
|
10
|
+
registry.set('codex', codexImportHandler);
|
|
11
|
+
builtinsRegistered = true;
|
|
12
|
+
}
|
|
13
|
+
export function registerImportHandler(handler) {
|
|
14
|
+
ensureBuiltinImportHandlersRegistered();
|
|
15
|
+
if (registry.has(handler.targetName)) {
|
|
16
|
+
throw new Error(`Importer for target "${handler.targetName}" is already registered`);
|
|
17
|
+
}
|
|
18
|
+
registry.set(handler.targetName, handler);
|
|
19
|
+
}
|
|
20
|
+
export function getImportHandler(targetName) {
|
|
21
|
+
ensureBuiltinImportHandlersRegistered();
|
|
22
|
+
return registry.get(targetName);
|
|
23
|
+
}
|
|
24
|
+
export function getImportHandlers() {
|
|
25
|
+
ensureBuiltinImportHandlersRegistered();
|
|
26
|
+
return Array.from(registry.values());
|
|
27
|
+
}
|
|
28
|
+
export function getDetectedImportHandlers(cwd) {
|
|
29
|
+
return getImportHandlers().filter((handler) => handler.detect(cwd));
|
|
30
|
+
}
|
|
31
|
+
export function importTargetFromDir(targetName, cwd, projectName) {
|
|
32
|
+
const handler = getImportHandler(targetName);
|
|
33
|
+
if (!handler) {
|
|
34
|
+
throw new Error(`Importer not found for target "${targetName}"`);
|
|
35
|
+
}
|
|
36
|
+
return handler.importFromDir(cwd, projectName);
|
|
510
37
|
}
|
|
511
38
|
//# sourceMappingURL=index.js.map
|