@colin4k1024/tsp 2.4.5 → 2.4.6
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 +16 -20
- package/bin/lib/install-surface.js +3 -3
- package/bin/lib/source-installer.js +2 -2
- package/commands/team-help.md +2 -2
- package/commands/team-plan.md +1 -1
- package/commands/update-codemaps.md +3 -3
- package/manifests/install-components.json +1 -1
- package/manifests/install-modules.json +17 -3
- package/manifests/install-profiles.json +2 -0
- package/package.json +6 -3
- package/schemas/ecc-install-config.schema.json +6 -1
- package/schemas/install-modules.schema.json +4 -1
- package/scripts/codegraph-preflight.js +179 -0
- package/scripts/gitnexus-preflight.js +8 -0
- package/scripts/install-apply.js +10 -8
- package/scripts/install-codegraph.js +158 -0
- package/scripts/install-plan.js +28 -11
- package/scripts/lib/install/apply.js +256 -5
- package/scripts/lib/install/request.js +3 -2
- package/scripts/lib/install-audit-manifest.js +3 -0
- package/scripts/lib/install-executor.js +14 -5
- package/scripts/lib/install-lifecycle.js +2 -2
- package/scripts/lib/install-manifests.js +23 -4
- package/scripts/lib/install-targets/codex-home.js +187 -1
- package/scripts/lib/install-targets/opencode-home.js +135 -2
- package/scripts/lib/install-targets/registry.js +23 -1
- package/scripts/lib/release-health.js +19 -4
- package/scripts/lib/team-skills-data.json +6 -6
- package/scripts/release-health-summary.js +1 -1
- package/scripts/workflow-help.js +3 -3
- package/skills/codegraph/SKILL.md +57 -0
- package/skills/codegraph/agents/openai.yaml +4 -0
- package/docs/.vitepress/config.mts +0 -199
- package/docs/adr/ADR-001-doc-architecture-integration.md +0 -33
- package/docs/guides/README.md +0 -5
- package/docs/guides/installation.md +0 -33
- package/docs/guides/user-guide.md +0 -36
- package/docs/index.md +0 -65
- package/docs/memory/backlog.md +0 -10
- package/docs/memory/decisions.md +0 -43
- package/docs/memory/lessons-learned.md +0 -87
- package/docs/plans/2026-04-03-python-remnants-audit.md +0 -265
- package/docs/plans/2026-04-03-scripts-python-to-js-migration.md +0 -372
- package/docs/plans/2026-04-03-solo-delivery-execution-checklist.md +0 -413
- package/docs/plans/2026-04-03-solo-delivery-gap-plan.md +0 -377
- package/docs/plans/2026-04-03-team-skills-workflow-gates.md +0 -548
- package/docs/plans/2026-04-21-open-source-readiness-gap-plan.md +0 -217
- package/docs/plans/llm-surface-reduction-audit.md +0 -147
- package/docs/plans/llm-surface-reduction-execution-checklist.md +0 -217
- package/docs/plans/llm-surface-reduction-execution-history.md +0 -124
- package/docs/plans/team-skills-platform-migration.md +0 -54
- package/docs/presentation/README.md +0 -42
- package/docs/presentation/audience-presentation-route-map.md +0 -84
- package/docs/presentation/executive-briefing-talk-track.md +0 -50
- package/docs/presentation/generate_capability_matrix.py +0 -396
- package/docs/presentation/generate_ppt.py +0 -354
- package/docs/presentation/implementation-onboarding-brief.md +0 -38
- package/docs/presentation/presentation-talk-track.md +0 -97
- package/docs/presentation/vertical-scenario-route-map.md +0 -99
- package/docs/presentation/workshop-facilitator-guide.md +0 -47
- package/docs/runbooks/actionlint-workflow-gates.md +0 -80
- package/docs/runbooks/agent-governance.md +0 -131
- package/docs/runbooks/ai-eval-platform-demo-execution-log.md +0 -147
- package/docs/runbooks/ai-eval-platform-demo-script.md +0 -136
- package/docs/runbooks/ai-eval-platform-walkthrough.md +0 -113
- package/docs/runbooks/ai-pr-review-automation.md +0 -56
- package/docs/runbooks/api-breaking-change-gates.md +0 -58
- package/docs/runbooks/api-design-evolution-walkthrough.md +0 -42
- package/docs/runbooks/api-lint-gates.md +0 -57
- package/docs/runbooks/api-mocking-strategy-and-lifecycle-guide.md +0 -47
- package/docs/runbooks/architect-daily-operations.md +0 -63
- package/docs/runbooks/architect-design-conversation-example.md +0 -83
- package/docs/runbooks/artifact-attestation-gates.md +0 -75
- package/docs/runbooks/artifact-persistence.md +0 -257
- package/docs/runbooks/backend-engineer-daily-operations.md +0 -63
- package/docs/runbooks/batch-optimization-completion-checklist.md +0 -104
- package/docs/runbooks/biz-service-designer-end-to-end-conversation-example.md +0 -5
- package/docs/runbooks/biz-service-designer-toolkit.md +0 -5
- package/docs/runbooks/bug-fix-complete-walkthrough.md +0 -60
- package/docs/runbooks/build-failure-recovery-walkthrough.md +0 -40
- package/docs/runbooks/canary-decision-matrix.md +0 -41
- package/docs/runbooks/canary-staging-release-walkthrough.md +0 -46
- package/docs/runbooks/checkov-iac-gates.md +0 -104
- package/docs/runbooks/claude-code-review-workflow.md +0 -72
- package/docs/runbooks/claude-conversation-prompt-recipes.md +0 -132
- package/docs/runbooks/claude-end-to-end-conversation-example.md +0 -198
- package/docs/runbooks/claude-feature-development-guide.md +0 -112
- package/docs/runbooks/claude-quick-start.md +0 -227
- package/docs/runbooks/claude-usage-scenarios.md +0 -176
- package/docs/runbooks/code-review-collaboration-walkthrough.md +0 -65
- package/docs/runbooks/codeql-pr-security-gates.md +0 -64
- package/docs/runbooks/codex-end-to-end-conversation-example.md +0 -166
- package/docs/runbooks/codex-multi-agent-orchestration.md +0 -65
- package/docs/runbooks/codex-parallel-prompt-recipes.md +0 -131
- package/docs/runbooks/codex-quick-start.md +0 -223
- package/docs/runbooks/codex-usage-scenarios.md +0 -168
- package/docs/runbooks/codex-workflow-essentials.md +0 -88
- package/docs/runbooks/command-and-capability-matrix.md +0 -162
- package/docs/runbooks/conftest-policy-gates.md +0 -84
- package/docs/runbooks/consumer-driven-contract-testing-with-mock-alignment.md +0 -45
- package/docs/runbooks/contract-testing-playbook.md +0 -78
- package/docs/runbooks/cosign-signing-gates.md +0 -71
- package/docs/runbooks/cross-role-issue-triage-walkthrough.md +0 -47
- package/docs/runbooks/cursor-quick-start.md +0 -123
- package/docs/runbooks/custom-overlay.md +0 -115
- package/docs/runbooks/data-ml-pipeline-demo-execution-log.md +0 -141
- package/docs/runbooks/data-ml-pipeline-demo-script.md +0 -102
- package/docs/runbooks/data-ml-pipeline-walkthrough.md +0 -119
- package/docs/runbooks/data-observability-quality-demo-execution-log.md +0 -36
- package/docs/runbooks/data-observability-quality-demo-script.md +0 -42
- package/docs/runbooks/data-observability-quality-walkthrough.md +0 -86
- package/docs/runbooks/demo-deliverables-overview.md +0 -278
- package/docs/runbooks/demo-execution-log.md +0 -530
- package/docs/runbooks/demo-scenario.md +0 -129
- package/docs/runbooks/dependency-review-gates.md +0 -63
- package/docs/runbooks/dependency-update-automation.md +0 -83
- package/docs/runbooks/design-md-workflow.md +0 -185
- package/docs/runbooks/devops-engineer-daily-operations.md +0 -60
- package/docs/runbooks/devops-release-conversation-example.md +0 -88
- package/docs/runbooks/doc-architecture-integration.md +0 -59
- package/docs/runbooks/doc-architecture-quick-start.md +0 -122
- package/docs/runbooks/document-execution-audit.md +0 -32
- package/docs/runbooks/documentation-update-walkthrough.md +0 -37
- package/docs/runbooks/ecc-harness-usage.md +0 -93
- package/docs/runbooks/error-experience-usage.md +0 -116
- package/docs/runbooks/evolution-usage.md +0 -162
- package/docs/runbooks/executive-value-one-page.md +0 -55
- package/docs/runbooks/external-capability-approval-and-enablement-workflow.md +0 -39
- package/docs/runbooks/external-capability-intake.md +0 -160
- package/docs/runbooks/first-team-command-60-seconds.md +0 -96
- package/docs/runbooks/first-team-workflow-walkthrough.md +0 -245
- package/docs/runbooks/frontend-backend-integration-acceptance-checklist.md +0 -46
- package/docs/runbooks/frontend-backend-parallel-integration-walkthrough.md +0 -48
- package/docs/runbooks/frontend-bugfix-one-page.md +0 -82
- package/docs/runbooks/frontend-engineer-daily-operations.md +0 -60
- package/docs/runbooks/frontend-enterprise-style-profile.md +0 -5
- package/docs/runbooks/frontend-governance.md +0 -47
- package/docs/runbooks/frontend-refactor-walkthrough.md +0 -42
- package/docs/runbooks/git-pr-workflow.md +0 -63
- package/docs/runbooks/github-actions-supply-chain-demo-execution-log.md +0 -158
- package/docs/runbooks/github-actions-supply-chain-demo-script.md +0 -150
- package/docs/runbooks/github-actions-supply-chain-walkthrough.md +0 -117
- package/docs/runbooks/github-token-permissions-baseline.md +0 -92
- package/docs/runbooks/gitlab-manual-pipeline-release.md +0 -5
- package/docs/runbooks/gitlab-release-integration-playbook.md +0 -5
- package/docs/runbooks/gitnexus-code-intelligence-usage.md +0 -133
- package/docs/runbooks/graphify-knowledge-graph-usage.md +0 -88
- package/docs/runbooks/handoff-filling-guide-with-examples.md +0 -70
- package/docs/runbooks/handoff-governance.md +0 -250
- package/docs/runbooks/helm-unittest-playbook.md +0 -101
- package/docs/runbooks/hotfix-emergency-release-walkthrough.md +0 -60
- package/docs/runbooks/iac-kubernetes-platform-demo-execution-log.md +0 -144
- package/docs/runbooks/iac-kubernetes-platform-demo-script.md +0 -130
- package/docs/runbooks/iac-kubernetes-platform-walkthrough.md +0 -120
- package/docs/runbooks/implementation-onboarding-reading-path.md +0 -67
- package/docs/runbooks/in-toto-attestation-framework.md +0 -94
- package/docs/runbooks/incident-severity-triage-tree.md +0 -43
- package/docs/runbooks/incident-triage-one-page.md +0 -65
- package/docs/runbooks/internal-developer-platform-demo-execution-log.md +0 -36
- package/docs/runbooks/internal-developer-platform-demo-script.md +0 -42
- package/docs/runbooks/internal-developer-platform-walkthrough.md +0 -91
- package/docs/runbooks/karpathy-guidelines-usage.md +0 -27
- package/docs/runbooks/kubeconform-schema-gates.md +0 -100
- package/docs/runbooks/kubectl-server-dry-run-gates.md +0 -103
- package/docs/runbooks/kyverno-policy-gates.md +0 -90
- package/docs/runbooks/langfuse-and-observability-integration-guide.md +0 -43
- package/docs/runbooks/langfuse-coding-trace.md +0 -44
- package/docs/runbooks/mobile-miniapp-delivery-walkthrough.md +0 -112
- package/docs/runbooks/mobile-miniapp-demo-execution-log.md +0 -139
- package/docs/runbooks/mobile-miniapp-demo-script.md +0 -129
- package/docs/runbooks/multi-service-backend-integration-walkthrough.md +0 -61
- package/docs/runbooks/open-design-integration.md +0 -163
- package/docs/runbooks/open-source-release-checklist.md +0 -90
- package/docs/runbooks/opencode-quick-start.md +0 -128
- package/docs/runbooks/parallel-development-coordination-walkthrough.md +0 -47
- package/docs/runbooks/parallel-execution-usage.md +0 -179
- package/docs/runbooks/platform-capability-demo-execution-log.md +0 -184
- package/docs/runbooks/platform-capability-demo-script.md +0 -192
- package/docs/runbooks/plugin-extension-platform-demo-execution-log.md +0 -136
- package/docs/runbooks/plugin-extension-platform-demo-script.md +0 -102
- package/docs/runbooks/plugin-extension-platform-walkthrough.md +0 -111
- package/docs/runbooks/policy-controller-gates.md +0 -75
- package/docs/runbooks/post-rollback-verification-checklist.md +0 -37
- package/docs/runbooks/pre-release-checklist.md +0 -50
- package/docs/runbooks/product-manager-clarification-conversation-example.md +0 -90
- package/docs/runbooks/product-manager-daily-operations.md +0 -60
- package/docs/runbooks/production-incident-response-walkthrough.md +0 -50
- package/docs/runbooks/project-claude-design-rationale.md +0 -188
- package/docs/runbooks/project-manager-daily-operations.md +0 -61
- package/docs/runbooks/project-manager-planning-conversation-example.md +0 -82
- package/docs/runbooks/project-onboarding.md +0 -452
- package/docs/runbooks/qa-engineer-daily-operations.md +0 -63
- package/docs/runbooks/qa-review-conversation-example.md +0 -87
- package/docs/runbooks/release-closure-one-page.md +0 -65
- package/docs/runbooks/release-governance-reading-path.md +0 -56
- package/docs/runbooks/release-notes-automation.md +0 -48
- package/docs/runbooks/release-rollback-recovery-walkthrough.md +0 -47
- package/docs/runbooks/requirement-clarity-and-scope-walkthrough.md +0 -46
- package/docs/runbooks/reviewdog-pr-gates.md +0 -49
- package/docs/runbooks/role-prompt-recipes.md +0 -130
- package/docs/runbooks/rtk-integration-intake.md +0 -45
- package/docs/runbooks/rtk-token-optimization-usage.md +0 -107
- package/docs/runbooks/runner-egress-hardening.md +0 -81
- package/docs/runbooks/runtime-capabilities-overview.md +0 -113
- package/docs/runbooks/sbom-generation-gates.md +0 -71
- package/docs/runbooks/scorecard-supply-chain-gates.md +0 -82
- package/docs/runbooks/secret-scanning-gates.md +0 -85
- package/docs/runbooks/security-compliance-platform-demo-execution-log.md +0 -36
- package/docs/runbooks/security-compliance-platform-demo-script.md +0 -49
- package/docs/runbooks/security-compliance-platform-walkthrough.md +0 -98
- package/docs/runbooks/slsa-generator-patterns.md +0 -73
- package/docs/runbooks/slsa-verification-gates.md +0 -75
- package/docs/runbooks/solo-delivery-mode.md +0 -142
- package/docs/runbooks/solo-delivery-one-page.md +0 -111
- package/docs/runbooks/specialist-commands-playbook.md +0 -85
- package/docs/runbooks/sub-agent-invocation-map.md +0 -144
- package/docs/runbooks/system-architecture-design-walkthrough.md +0 -49
- package/docs/runbooks/team-closeout-example.md +0 -73
- package/docs/runbooks/team-command-output-contracts.md +0 -358
- package/docs/runbooks/team-commands-quick-prompts.md +0 -125
- package/docs/runbooks/team-execute-example.md +0 -63
- package/docs/runbooks/team-handoff-example.md +0 -49
- package/docs/runbooks/team-intake-example.md +0 -70
- package/docs/runbooks/team-plan-example.md +0 -62
- package/docs/runbooks/team-release-example.md +0 -63
- package/docs/runbooks/team-review-example.md +0 -61
- package/docs/runbooks/team-skills-test-run.md +0 -184
- package/docs/runbooks/team-skills-usage.md +0 -336
- package/docs/runbooks/team-training-reading-path.md +0 -64
- package/docs/runbooks/tech-lead-closure-conversation-example.md +0 -78
- package/docs/runbooks/tech-lead-daily-operations.md +0 -67
- package/docs/runbooks/trivy-security-gates.md +0 -79
- package/docs/runbooks/troubleshooting.md +0 -234
- package/docs/runbooks/vertical-scenario-capability-matrix.md +0 -107
- package/docs/runbooks/witness-policy-gates.md +0 -78
- package/docs/runbooks/zizmor-workflow-audits.md +0 -81
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
const path = require('path')
|
|
5
|
+
const { spawnSync } = require('child_process')
|
|
6
|
+
|
|
7
|
+
const SUPPORTED_TARGETS = Object.freeze({
|
|
8
|
+
claude: 'claude',
|
|
9
|
+
codex: 'codex',
|
|
10
|
+
cursor: 'cursor',
|
|
11
|
+
opencode: 'opencode',
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
function normalizeTarget(value) {
|
|
15
|
+
return String(value || '').trim().toLowerCase()
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function mapTarget(value) {
|
|
19
|
+
return SUPPORTED_TARGETS[normalizeTarget(value)] || null
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function parseArgs(argv) {
|
|
23
|
+
const parsed = {
|
|
24
|
+
target: process.env.TSP_INSTALL_TARGET || '',
|
|
25
|
+
dryRun: process.env.CODEGRAPH_INSTALL_DRY_RUN === '1',
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
29
|
+
const arg = argv[index]
|
|
30
|
+
if (arg === '--target') {
|
|
31
|
+
parsed.target = argv[index + 1] || ''
|
|
32
|
+
index += 1
|
|
33
|
+
continue
|
|
34
|
+
}
|
|
35
|
+
if (arg.startsWith('--target=')) {
|
|
36
|
+
parsed.target = arg.slice('--target='.length)
|
|
37
|
+
continue
|
|
38
|
+
}
|
|
39
|
+
if (arg === '--dry-run') {
|
|
40
|
+
parsed.dryRun = true
|
|
41
|
+
continue
|
|
42
|
+
}
|
|
43
|
+
if (arg === '--help' || arg === '-h') {
|
|
44
|
+
parsed.help = true
|
|
45
|
+
continue
|
|
46
|
+
}
|
|
47
|
+
throw new Error(`Unknown argument: ${arg}`)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return parsed
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function resolveCodeGraphBin() {
|
|
54
|
+
if (process.env.CODEGRAPH_INSTALL_BIN) {
|
|
55
|
+
return {
|
|
56
|
+
command: process.env.CODEGRAPH_INSTALL_BIN,
|
|
57
|
+
argsPrefix: [],
|
|
58
|
+
displayCommand: process.env.CODEGRAPH_INSTALL_BIN,
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
let packageJsonPath
|
|
63
|
+
try {
|
|
64
|
+
packageJsonPath = require.resolve('@colbymchenry/codegraph/package.json')
|
|
65
|
+
} catch (error) {
|
|
66
|
+
throw new Error(
|
|
67
|
+
'Unable to resolve @colbymchenry/codegraph. Run npm install before applying the CodeGraph integration.'
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const binPath = path.join(path.dirname(packageJsonPath), 'dist', 'bin', 'codegraph.js')
|
|
72
|
+
return {
|
|
73
|
+
command: process.execPath,
|
|
74
|
+
argsPrefix: [binPath],
|
|
75
|
+
displayCommand: `${process.execPath} ${binPath}`,
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function buildInstallCommand(target) {
|
|
80
|
+
const mappedTarget = mapTarget(target)
|
|
81
|
+
if (!mappedTarget) {
|
|
82
|
+
return {
|
|
83
|
+
supported: false,
|
|
84
|
+
target: normalizeTarget(target),
|
|
85
|
+
reason: `CodeGraph upstream installer does not support TSP target: ${target || '(missing)'}`,
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const resolved = resolveCodeGraphBin()
|
|
90
|
+
const args = [
|
|
91
|
+
...resolved.argsPrefix,
|
|
92
|
+
'install',
|
|
93
|
+
`--target=${mappedTarget}`,
|
|
94
|
+
'--location=global',
|
|
95
|
+
'--yes',
|
|
96
|
+
]
|
|
97
|
+
|
|
98
|
+
return {
|
|
99
|
+
supported: true,
|
|
100
|
+
target: mappedTarget,
|
|
101
|
+
command: resolved.command,
|
|
102
|
+
args,
|
|
103
|
+
display: [resolved.displayCommand, ...args.slice(resolved.argsPrefix.length)].join(' '),
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function printHelp() {
|
|
108
|
+
console.log(`Usage: node scripts/install-codegraph.js [--target <claude|codex|cursor|opencode>] [--dry-run]
|
|
109
|
+
|
|
110
|
+
Runs the upstream CodeGraph installer for the current TSP install target only.
|
|
111
|
+
The project index is not initialized here; run codegraph init -i inside a target project when needed.
|
|
112
|
+
`)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function run(argv = process.argv.slice(2)) {
|
|
116
|
+
const options = parseArgs(argv)
|
|
117
|
+
if (options.help) {
|
|
118
|
+
printHelp()
|
|
119
|
+
return 0
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const install = buildInstallCommand(options.target)
|
|
123
|
+
if (!install.supported) {
|
|
124
|
+
console.error(`Skipping CodeGraph installer: ${install.reason}`)
|
|
125
|
+
return 0
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (options.dryRun) {
|
|
129
|
+
console.log(`CodeGraph install command: ${install.display}`)
|
|
130
|
+
return 0
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
console.error(`Running CodeGraph installer for ${install.target}`)
|
|
134
|
+
const result = spawnSync(install.command, install.args, {
|
|
135
|
+
cwd: process.cwd(),
|
|
136
|
+
env: process.env,
|
|
137
|
+
encoding: 'utf8',
|
|
138
|
+
stdio: ['inherit', process.stderr, process.stderr],
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
return typeof result.status === 'number' ? result.status : 1
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (require.main === module) {
|
|
145
|
+
try {
|
|
146
|
+
process.exit(run())
|
|
147
|
+
} catch (error) {
|
|
148
|
+
console.error(error.message || error)
|
|
149
|
+
process.exit(1)
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
module.exports = {
|
|
154
|
+
buildInstallCommand,
|
|
155
|
+
mapTarget,
|
|
156
|
+
parseArgs,
|
|
157
|
+
run,
|
|
158
|
+
}
|
package/scripts/install-plan.js
CHANGED
|
@@ -137,6 +137,30 @@ function printComponents(components) {
|
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
+
function resolvePlanExternalInstalls(plan) {
|
|
141
|
+
return plan.selectedModules
|
|
142
|
+
.map(module => ({ module, externalInstall: module.externalInstall }))
|
|
143
|
+
.filter(({ externalInstall }) => externalInstall && typeof externalInstall === 'object' && !Array.isArray(externalInstall))
|
|
144
|
+
.filter(({ externalInstall }) => {
|
|
145
|
+
const profiles = Array.isArray(externalInstall.profiles)
|
|
146
|
+
? externalInstall.profiles.map(value => String(value).trim()).filter(Boolean)
|
|
147
|
+
: [];
|
|
148
|
+
return profiles.length === 0 || profiles.includes(plan.profileId);
|
|
149
|
+
})
|
|
150
|
+
.map(({ module, externalInstall }) => ({
|
|
151
|
+
id: externalInstall.id || module.id,
|
|
152
|
+
moduleId: module.id,
|
|
153
|
+
description: externalInstall.description || '',
|
|
154
|
+
command: externalInstall.command || 'node',
|
|
155
|
+
script: externalInstall.script || null,
|
|
156
|
+
args: Array.isArray(externalInstall.args)
|
|
157
|
+
? externalInstall.args.map(value => String(value))
|
|
158
|
+
: [],
|
|
159
|
+
target: plan.target || null,
|
|
160
|
+
profileId: plan.profileId || null,
|
|
161
|
+
}));
|
|
162
|
+
}
|
|
163
|
+
|
|
140
164
|
function printPlan(plan) {
|
|
141
165
|
console.log('Install plan:\n');
|
|
142
166
|
console.log(
|
|
@@ -184,20 +208,12 @@ function printPlan(plan) {
|
|
|
184
208
|
}
|
|
185
209
|
}
|
|
186
210
|
|
|
187
|
-
const externalInstalls = plan
|
|
188
|
-
.map(module => ({ module, externalInstall: module.externalInstall }))
|
|
189
|
-
.filter(({ externalInstall }) => externalInstall && typeof externalInstall === 'object' && !Array.isArray(externalInstall))
|
|
190
|
-
.filter(({ externalInstall }) => {
|
|
191
|
-
const profiles = Array.isArray(externalInstall.profiles)
|
|
192
|
-
? externalInstall.profiles.map(value => String(value).trim()).filter(Boolean)
|
|
193
|
-
: [];
|
|
194
|
-
return profiles.length === 0 || profiles.includes(plan.profileId);
|
|
195
|
-
});
|
|
211
|
+
const externalInstalls = resolvePlanExternalInstalls(plan);
|
|
196
212
|
if (externalInstalls.length > 0) {
|
|
197
213
|
console.log('');
|
|
198
214
|
console.log(`External install plan (${externalInstalls.length}):`);
|
|
199
|
-
for (const
|
|
200
|
-
console.log(`- ${externalInstall.id
|
|
215
|
+
for (const externalInstall of externalInstalls) {
|
|
216
|
+
console.log(`- ${externalInstall.id}: ${externalInstall.description || externalInstall.script}`);
|
|
201
217
|
}
|
|
202
218
|
}
|
|
203
219
|
}
|
|
@@ -268,6 +284,7 @@ function main() {
|
|
|
268
284
|
excludeComponentIds: request.excludeComponentIds,
|
|
269
285
|
target: request.target,
|
|
270
286
|
});
|
|
287
|
+
plan.externalInstalls = resolvePlanExternalInstalls(plan);
|
|
271
288
|
|
|
272
289
|
if (options.json) {
|
|
273
290
|
console.log(JSON.stringify(plan, null, 2));
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const fs = require('fs');
|
|
4
|
+
const os = require('os');
|
|
4
5
|
const path = require('path');
|
|
5
6
|
const { spawnSync } = require('child_process');
|
|
6
7
|
|
|
7
8
|
const { writeInstallState } = require('../install-state');
|
|
8
9
|
const { writeInstallAuditManifest } = require('../install-audit-manifest');
|
|
9
10
|
|
|
11
|
+
const PLUGIN_NAME = require('../team-skills-data.json').plugin.name;
|
|
12
|
+
const OPENCODE_AGENTS_MD_MARKER = '<!-- team-skills-platform -->';
|
|
13
|
+
|
|
10
14
|
function readJsonObject(filePath, label) {
|
|
11
15
|
let parsed;
|
|
12
16
|
try {
|
|
@@ -177,6 +181,16 @@ function buildMergedSettings(plan) {
|
|
|
177
181
|
};
|
|
178
182
|
}
|
|
179
183
|
|
|
184
|
+
function buildExternalInstallEnv(externalInstall) {
|
|
185
|
+
return {
|
|
186
|
+
...process.env,
|
|
187
|
+
...(externalInstall.env || {}),
|
|
188
|
+
TSP_INSTALL_TARGET: externalInstall.target || '',
|
|
189
|
+
TSP_INSTALL_PROFILE: externalInstall.profileId || '',
|
|
190
|
+
TSP_INSTALL_MODULE_ID: externalInstall.moduleId || '',
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
180
194
|
function runExternalInstall(externalInstall) {
|
|
181
195
|
const args = [];
|
|
182
196
|
if (externalInstall.scriptPath) {
|
|
@@ -190,12 +204,18 @@ function runExternalInstall(externalInstall) {
|
|
|
190
204
|
|
|
191
205
|
const command = externalInstall.command || 'node';
|
|
192
206
|
const label = externalInstall.id || externalInstall.moduleId || command;
|
|
193
|
-
|
|
207
|
+
if (process.env.TSP_SKIP_EXTERNAL_INSTALLS === '1') {
|
|
208
|
+
console.error(`Skipping external install: ${label}`);
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
console.error(`Running external install: ${label}`);
|
|
194
213
|
|
|
195
214
|
const result = spawnSync(command, args, {
|
|
196
215
|
cwd: externalInstall.cwd || process.cwd(),
|
|
216
|
+
env: buildExternalInstallEnv(externalInstall),
|
|
197
217
|
encoding: 'utf8',
|
|
198
|
-
stdio: 'inherit',
|
|
218
|
+
stdio: ['inherit', process.stderr, process.stderr],
|
|
199
219
|
});
|
|
200
220
|
|
|
201
221
|
if (result.status !== 0) {
|
|
@@ -203,6 +223,232 @@ function runExternalInstall(externalInstall) {
|
|
|
203
223
|
}
|
|
204
224
|
}
|
|
205
225
|
|
|
226
|
+
function mergePluginMarketplace(sourceMarketplace, targetMarketplace) {
|
|
227
|
+
if (!fs.existsSync(sourceMarketplace)) {
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const source = readJsonObject(sourceMarketplace, 'source marketplace');
|
|
232
|
+
let target = {
|
|
233
|
+
name: source.name || 'marketplace',
|
|
234
|
+
interface: source.interface || {},
|
|
235
|
+
plugins: [],
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
if (fs.existsSync(targetMarketplace)) {
|
|
239
|
+
target = readJsonObject(targetMarketplace, 'target marketplace');
|
|
240
|
+
if (!Array.isArray(target.plugins)) {
|
|
241
|
+
target.plugins = [];
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const targetPlugins = target.plugins || [];
|
|
246
|
+
const nextPluginsByName = new Map();
|
|
247
|
+
for (const plugin of targetPlugins) {
|
|
248
|
+
if (plugin && typeof plugin.name === 'string') {
|
|
249
|
+
nextPluginsByName.set(plugin.name, plugin);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
for (const plugin of source.plugins || []) {
|
|
253
|
+
if (plugin && typeof plugin.name === 'string') {
|
|
254
|
+
nextPluginsByName.set(plugin.name, plugin);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
target.plugins = [...nextPluginsByName.values()];
|
|
259
|
+
fs.mkdirSync(path.dirname(targetMarketplace), { recursive: true });
|
|
260
|
+
fs.writeFileSync(targetMarketplace, JSON.stringify(target, null, 2) + '\n', 'utf8');
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
function registerCodexPlugin(plan) {
|
|
264
|
+
const configPath = path.join(plan.targetRoot, 'config.toml');
|
|
265
|
+
const marker = `[plugins."${PLUGIN_NAME}"]`;
|
|
266
|
+
const content = fs.existsSync(configPath) ? fs.readFileSync(configPath, 'utf8') : '';
|
|
267
|
+
if (!content.includes(marker)) {
|
|
268
|
+
const entry = `\n${marker}\nenabled = true\n`;
|
|
269
|
+
fs.mkdirSync(path.dirname(configPath), { recursive: true });
|
|
270
|
+
fs.writeFileSync(configPath, `${content.replace(/\n+$/, '')}${entry}`, 'utf8');
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
const homeDir = path.basename(plan.targetRoot) === '.codex'
|
|
274
|
+
? path.dirname(plan.targetRoot)
|
|
275
|
+
: (process.env.HOME || os.homedir());
|
|
276
|
+
const agentsHome = process.env.AGENTS_HOME_DIR || path.join(homeDir, '.agents');
|
|
277
|
+
mergePluginMarketplace(
|
|
278
|
+
path.join(plan.targetRoot, 'plugins', PLUGIN_NAME, '.agents', 'plugins', 'marketplace.json'),
|
|
279
|
+
path.join(agentsHome, 'plugins', 'marketplace.json')
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
function buildOpenCodeAgentsMd(pluginRoot) {
|
|
284
|
+
const agentsDir = path.join(pluginRoot, 'agents', 'roles');
|
|
285
|
+
const roleNames = fs.existsSync(agentsDir)
|
|
286
|
+
? fs
|
|
287
|
+
.readdirSync(agentsDir)
|
|
288
|
+
.filter((name) => name.endsWith('.md'))
|
|
289
|
+
.map((name) => path.parse(name).name)
|
|
290
|
+
.sort()
|
|
291
|
+
: [];
|
|
292
|
+
const roleDisplay = {
|
|
293
|
+
'tech-lead': 'Tech Lead(技术负责人)',
|
|
294
|
+
'product-manager': 'Product Manager(产品经理)',
|
|
295
|
+
'project-manager': 'Project Manager(项目管理)',
|
|
296
|
+
architect: 'Architect(架构师)',
|
|
297
|
+
'frontend-engineer': 'Frontend Engineer(前端开发)',
|
|
298
|
+
'backend-engineer': 'Backend Engineer(后端开发)',
|
|
299
|
+
'qa-engineer': 'QA Engineer(测试工程师)',
|
|
300
|
+
'devops-engineer': 'DevOps Engineer(运维工程师)',
|
|
301
|
+
};
|
|
302
|
+
const lines = [
|
|
303
|
+
OPENCODE_AGENTS_MD_MARKER,
|
|
304
|
+
'# Team Skills Platform — OpenCode Agent Index',
|
|
305
|
+
'',
|
|
306
|
+
'本文件由安装脚本自动生成。在 OpenCode 中与任何角色交互时,可直接引用下列角色和命令。',
|
|
307
|
+
'',
|
|
308
|
+
'## 可用角色',
|
|
309
|
+
'',
|
|
310
|
+
];
|
|
311
|
+
for (const role of roleNames) {
|
|
312
|
+
lines.push(`- **${roleDisplay[role] || role}**: \`plugins/${PLUGIN_NAME}/agents/roles/${role}.md\``);
|
|
313
|
+
}
|
|
314
|
+
lines.push(
|
|
315
|
+
'',
|
|
316
|
+
'## 核心团队命令',
|
|
317
|
+
'',
|
|
318
|
+
'| 命令 | 用途 |',
|
|
319
|
+
'|------|------|',
|
|
320
|
+
'| `/team-help` | 根据当前阶段、artifacts 与阻塞项推荐下一步主链命令 |',
|
|
321
|
+
'| `/team-intake` | 接收需求并锁定目标、范围、约束 |',
|
|
322
|
+
'| `/team-plan` | 拆解任务、角色分工、依赖与里程碑 |',
|
|
323
|
+
'| `/team-execute` | 驱动研发角色在边界内实施 |',
|
|
324
|
+
'| `/team-review` | 做方案、质量、测试和放行评审 |',
|
|
325
|
+
'| `/team-release` | 做发布准备、上线检查与回滚保障 |',
|
|
326
|
+
'| `/team-closeout` | 在观察窗口结束后做最终收口与 backlog 回写 |',
|
|
327
|
+
'| `/handoff` | 在角色间做结构化交接 |',
|
|
328
|
+
'',
|
|
329
|
+
'## 插件根路径',
|
|
330
|
+
'',
|
|
331
|
+
'`~/.config/opencode/plugins/team-skills-platform/`',
|
|
332
|
+
'',
|
|
333
|
+
`<!-- end ${PLUGIN_NAME} -->`
|
|
334
|
+
);
|
|
335
|
+
return `${lines.join('\n')}\n`;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
function mergeOpenCodeAgentsMd(targetPath, newContent) {
|
|
339
|
+
const markerEnd = `<!-- end ${PLUGIN_NAME} -->`;
|
|
340
|
+
if (!fs.existsSync(targetPath)) {
|
|
341
|
+
fs.mkdirSync(path.dirname(targetPath), { recursive: true });
|
|
342
|
+
fs.writeFileSync(targetPath, newContent, 'utf8');
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
const existing = fs.readFileSync(targetPath, 'utf8');
|
|
346
|
+
if (existing.includes(OPENCODE_AGENTS_MD_MARKER)) {
|
|
347
|
+
const startIdx = existing.indexOf(OPENCODE_AGENTS_MD_MARKER);
|
|
348
|
+
let endIdx = existing.indexOf(markerEnd, startIdx);
|
|
349
|
+
if (endIdx !== -1) {
|
|
350
|
+
endIdx += markerEnd.length;
|
|
351
|
+
if (existing[endIdx] === '\n') {
|
|
352
|
+
endIdx += 1;
|
|
353
|
+
}
|
|
354
|
+
fs.writeFileSync(targetPath, `${existing.slice(0, startIdx)}${newContent}`, 'utf8');
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
const separator = existing.endsWith('\n') ? '\n' : '\n\n';
|
|
359
|
+
fs.writeFileSync(targetPath, `${existing}${separator}${newContent}`, 'utf8');
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
function mergeOpenCodeAgentsIndex(plan) {
|
|
363
|
+
const pluginRoot = path.join(plan.targetRoot, 'plugins', PLUGIN_NAME);
|
|
364
|
+
mergeOpenCodeAgentsMd(
|
|
365
|
+
path.join(plan.targetRoot, 'AGENTS.md'),
|
|
366
|
+
buildOpenCodeAgentsMd(pluginRoot)
|
|
367
|
+
);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
function applyTargetPostInstall(plan) {
|
|
371
|
+
if (plan.adapter && plan.adapter.target === 'codex') {
|
|
372
|
+
registerCodexPlugin(plan);
|
|
373
|
+
}
|
|
374
|
+
if (plan.adapter && plan.adapter.target === 'opencode') {
|
|
375
|
+
mergeOpenCodeAgentsIndex(plan);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
function replaceOperationByDestination(operations, replacement) {
|
|
380
|
+
let replaced = false;
|
|
381
|
+
const nextOperations = operations.map((operation) => {
|
|
382
|
+
if (operation.destinationPath !== replacement.destinationPath) {
|
|
383
|
+
return { ...operation };
|
|
384
|
+
}
|
|
385
|
+
replaced = true;
|
|
386
|
+
return {
|
|
387
|
+
...operation,
|
|
388
|
+
...replacement,
|
|
389
|
+
};
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
if (!replaced) {
|
|
393
|
+
nextOperations.push(replacement);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
return nextOperations;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
function appendOperationIfMissing(operations, operation) {
|
|
400
|
+
if (operations.some((item) => item.destinationPath === operation.destinationPath)) {
|
|
401
|
+
return operations.map((item) => ({ ...item }));
|
|
402
|
+
}
|
|
403
|
+
return [...operations.map((item) => ({ ...item })), operation];
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
function buildPlanWithRuntimeManagedOperations(plan, mergedSettingsPlan) {
|
|
407
|
+
if (!mergedSettingsPlan) {
|
|
408
|
+
return plan;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
const renderedHooksConfig = JSON.stringify(mergedSettingsPlan.resolvedHooksConfig, null, 2) + '\n';
|
|
412
|
+
const hooksOperation = {
|
|
413
|
+
kind: 'render-template',
|
|
414
|
+
moduleId: 'hooks-runtime',
|
|
415
|
+
sourceRelativePath: path.join('hooks', 'hooks.json'),
|
|
416
|
+
destinationPath: mergedSettingsPlan.hooksDestinationPath,
|
|
417
|
+
strategy: 'rendered-hooks-config',
|
|
418
|
+
ownership: 'managed',
|
|
419
|
+
scaffoldOnly: false,
|
|
420
|
+
renderedContent: renderedHooksConfig,
|
|
421
|
+
};
|
|
422
|
+
const settingsOperation = {
|
|
423
|
+
kind: 'merge-json',
|
|
424
|
+
moduleId: 'hooks-runtime',
|
|
425
|
+
sourceRelativePath: 'settings.json',
|
|
426
|
+
destinationPath: mergedSettingsPlan.settingsPath,
|
|
427
|
+
strategy: 'merge-claude-settings',
|
|
428
|
+
ownership: 'managed',
|
|
429
|
+
scaffoldOnly: false,
|
|
430
|
+
payload: {
|
|
431
|
+
hooks: mergedSettingsPlan.mergedSettings.hooks || {},
|
|
432
|
+
},
|
|
433
|
+
};
|
|
434
|
+
|
|
435
|
+
const rewriteOperations = (operations = []) => appendOperationIfMissing(
|
|
436
|
+
replaceOperationByDestination(operations, hooksOperation),
|
|
437
|
+
settingsOperation
|
|
438
|
+
);
|
|
439
|
+
|
|
440
|
+
return {
|
|
441
|
+
...plan,
|
|
442
|
+
operations: rewriteOperations(plan.operations),
|
|
443
|
+
statePreview: plan.statePreview
|
|
444
|
+
? {
|
|
445
|
+
...plan.statePreview,
|
|
446
|
+
operations: rewriteOperations(plan.statePreview.operations),
|
|
447
|
+
}
|
|
448
|
+
: plan.statePreview,
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
|
|
206
452
|
function applyInstallPlan(plan) {
|
|
207
453
|
const mergedSettingsPlan = buildMergedSettings(plan);
|
|
208
454
|
|
|
@@ -230,11 +476,14 @@ function applyInstallPlan(plan) {
|
|
|
230
476
|
runExternalInstall(externalInstall);
|
|
231
477
|
}
|
|
232
478
|
|
|
233
|
-
|
|
234
|
-
|
|
479
|
+
applyTargetPostInstall(plan);
|
|
480
|
+
|
|
481
|
+
const statefulPlan = buildPlanWithRuntimeManagedOperations(plan, mergedSettingsPlan);
|
|
482
|
+
writeInstallState(statefulPlan.installStatePath, statefulPlan.statePreview);
|
|
483
|
+
const { installManifestPath } = writeInstallAuditManifest(statefulPlan);
|
|
235
484
|
|
|
236
485
|
return {
|
|
237
|
-
...
|
|
486
|
+
...statefulPlan,
|
|
238
487
|
applied: true,
|
|
239
488
|
installManifestPath,
|
|
240
489
|
};
|
|
@@ -242,4 +491,6 @@ function applyInstallPlan(plan) {
|
|
|
242
491
|
|
|
243
492
|
module.exports = {
|
|
244
493
|
applyInstallPlan,
|
|
494
|
+
buildExternalInstallEnv,
|
|
495
|
+
runExternalInstall,
|
|
245
496
|
};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const { validateInstallModuleIds } = require('../install-manifests');
|
|
4
|
+
const { normalizeInstallTarget } = require('../install-targets/registry');
|
|
4
5
|
|
|
5
|
-
const LEGACY_INSTALL_TARGETS = ['claude', 'cursor', 'antigravity'];
|
|
6
|
+
const LEGACY_INSTALL_TARGETS = ['claude', 'cursor', 'antigravity', 'codex', 'opencode'];
|
|
6
7
|
|
|
7
8
|
function dedupeStrings(values) {
|
|
8
9
|
return [...new Set((Array.isArray(values) ? values : []).map(value => String(value).trim()).filter(Boolean))];
|
|
@@ -104,7 +105,7 @@ function normalizeInstallRequest(options = {}) {
|
|
|
104
105
|
...(Array.isArray(options.legacyLanguages) ? options.legacyLanguages : []),
|
|
105
106
|
...(Array.isArray(options.languages) ? options.languages : []),
|
|
106
107
|
]).map(language => language.toLowerCase()));
|
|
107
|
-
const target = options.target || config?.target || 'claude';
|
|
108
|
+
const target = normalizeInstallTarget(options.target || config?.target || 'claude');
|
|
108
109
|
const hasManifestBaseSelection = Boolean(profileId) || moduleIds.length > 0 || includeComponentIds.length > 0;
|
|
109
110
|
const usingManifestMode = hasManifestBaseSelection || excludeComponentIds.length > 0;
|
|
110
111
|
|
|
@@ -40,6 +40,9 @@ function normalizeOperations(operations) {
|
|
|
40
40
|
if (operation.ownership && operation.ownership !== 'managed') {
|
|
41
41
|
return false;
|
|
42
42
|
}
|
|
43
|
+
if (operation.kind === 'merge-json') {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
43
46
|
return typeof operation.destinationPath === 'string' && operation.destinationPath.length > 0;
|
|
44
47
|
});
|
|
45
48
|
}
|
|
@@ -10,7 +10,7 @@ const {
|
|
|
10
10
|
resolveLegacyCompatibilitySelection,
|
|
11
11
|
resolveInstallPlan,
|
|
12
12
|
} = require('./install-manifests');
|
|
13
|
-
const { getInstallTargetAdapter } = require('./install-targets/registry');
|
|
13
|
+
const { getInstallTargetAdapter, normalizeInstallTarget } = require('./install-targets/registry');
|
|
14
14
|
|
|
15
15
|
const LANGUAGE_NAME_PATTERN = /^[a-zA-Z0-9_-]+$/;
|
|
16
16
|
const EXCLUDED_GENERATED_SOURCE_SUFFIXES = [
|
|
@@ -85,7 +85,8 @@ function listAvailableLanguages(sourceRoot = getSourceRoot()) {
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
function validateLegacyTarget(target) {
|
|
88
|
-
|
|
88
|
+
const normalizedTarget = normalizeInstallTarget(target);
|
|
89
|
+
if (!LEGACY_INSTALL_TARGETS.includes(normalizedTarget)) {
|
|
89
90
|
throw new Error(
|
|
90
91
|
`Unknown install target: ${target}. Expected one of ${LEGACY_INSTALL_TARGETS.join(', ')}`
|
|
91
92
|
);
|
|
@@ -502,10 +503,18 @@ function createLegacyInstallPlan(options = {}) {
|
|
|
502
503
|
const sourceRoot = options.sourceRoot || getSourceRoot();
|
|
503
504
|
const projectRoot = options.projectRoot || process.cwd();
|
|
504
505
|
const homeDir = options.homeDir || process.env.HOME || os.homedir();
|
|
505
|
-
const target = options.target || 'claude';
|
|
506
|
+
const target = normalizeInstallTarget(options.target || 'claude');
|
|
506
507
|
|
|
507
508
|
validateLegacyTarget(target);
|
|
508
509
|
|
|
510
|
+
if (target === 'codex' || target === 'opencode') {
|
|
511
|
+
return createLegacyCompatInstallPlan({
|
|
512
|
+
...options,
|
|
513
|
+
target,
|
|
514
|
+
legacyLanguages: options.languages || options.legacyLanguages || [],
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
|
|
509
518
|
const context = {
|
|
510
519
|
sourceRoot,
|
|
511
520
|
projectRoot,
|
|
@@ -568,7 +577,7 @@ function createLegacyInstallPlan(options = {}) {
|
|
|
568
577
|
function createLegacyCompatInstallPlan(options = {}) {
|
|
569
578
|
const sourceRoot = options.sourceRoot || getSourceRoot();
|
|
570
579
|
const projectRoot = options.projectRoot || process.cwd();
|
|
571
|
-
const target = options.target || 'claude';
|
|
580
|
+
const target = normalizeInstallTarget(options.target || 'claude');
|
|
572
581
|
|
|
573
582
|
validateLegacyTarget(target);
|
|
574
583
|
|
|
@@ -637,7 +646,7 @@ function materializeScaffoldOperation(sourceRoot, operation) {
|
|
|
637
646
|
function createManifestInstallPlan(options = {}) {
|
|
638
647
|
const sourceRoot = options.sourceRoot || getSourceRoot();
|
|
639
648
|
const projectRoot = options.projectRoot || process.cwd();
|
|
640
|
-
const target = options.target || 'claude';
|
|
649
|
+
const target = normalizeInstallTarget(options.target || 'claude');
|
|
641
650
|
const legacyLanguages = Array.isArray(options.legacyLanguages)
|
|
642
651
|
? [...options.legacyLanguages]
|
|
643
652
|
: [];
|
|
@@ -14,7 +14,7 @@ const {
|
|
|
14
14
|
} = require('./install-executor');
|
|
15
15
|
const {
|
|
16
16
|
getInstallTargetAdapter,
|
|
17
|
-
|
|
17
|
+
listPublicInstallTargetAdapters,
|
|
18
18
|
} = require('./install-targets/registry');
|
|
19
19
|
|
|
20
20
|
const DEFAULT_REPO_ROOT = path.join(__dirname, '../..');
|
|
@@ -30,7 +30,7 @@ function readPackageVersion(repoRoot) {
|
|
|
30
30
|
|
|
31
31
|
function normalizeTargets(targets) {
|
|
32
32
|
if (!Array.isArray(targets) || targets.length === 0) {
|
|
33
|
-
return
|
|
33
|
+
return listPublicInstallTargetAdapters().map(adapter => adapter.target);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
const normalizedTargets = [];
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const os = require('os');
|
|
3
3
|
const path = require('path');
|
|
4
|
-
const {
|
|
4
|
+
const {
|
|
5
|
+
getInstallTargetAdapter,
|
|
6
|
+
normalizeInstallTarget,
|
|
7
|
+
planInstallTargetScaffold,
|
|
8
|
+
} = require('./install-targets/registry');
|
|
5
9
|
|
|
6
10
|
const DEFAULT_REPO_ROOT = path.join(__dirname, '../..');
|
|
7
11
|
const SUPPORTED_INSTALL_TARGETS = ['claude', 'cursor', 'antigravity', 'codex', 'gemini', 'opencode', 'codebuddy', 'copilot', 'windsurf', 'augment'];
|
|
@@ -35,6 +39,21 @@ const LEGACY_COMPAT_BASE_MODULE_IDS_BY_TARGET = Object.freeze({
|
|
|
35
39
|
'agents-core',
|
|
36
40
|
'commands-core',
|
|
37
41
|
],
|
|
42
|
+
codex: [
|
|
43
|
+
'rules-core',
|
|
44
|
+
'agents-core',
|
|
45
|
+
'commands-core',
|
|
46
|
+
'platform-configs',
|
|
47
|
+
'workflow-quality',
|
|
48
|
+
],
|
|
49
|
+
opencode: [
|
|
50
|
+
'rules-core',
|
|
51
|
+
'agents-core',
|
|
52
|
+
'commands-core',
|
|
53
|
+
'hooks-runtime',
|
|
54
|
+
'platform-configs',
|
|
55
|
+
'workflow-quality',
|
|
56
|
+
],
|
|
38
57
|
});
|
|
39
58
|
const LEGACY_LANGUAGE_ALIAS_TO_CANONICAL = Object.freeze({
|
|
40
59
|
cpp: 'cpp',
|
|
@@ -334,7 +353,7 @@ function validateInstallModuleIds(moduleIds, options = {}) {
|
|
|
334
353
|
function listInstallComponents(options = {}) {
|
|
335
354
|
const manifests = loadInstallManifests(options);
|
|
336
355
|
const family = options.family || null;
|
|
337
|
-
const target = options.target
|
|
356
|
+
const target = options.target ? normalizeInstallTarget(options.target) : null;
|
|
338
357
|
|
|
339
358
|
if (family && !Object.hasOwn(COMPONENT_FAMILY_PREFIXES, family)) {
|
|
340
359
|
throw new Error(
|
|
@@ -424,7 +443,7 @@ function expandComponentIdsToModuleIds(componentIds, manifests) {
|
|
|
424
443
|
|
|
425
444
|
function resolveLegacyCompatibilitySelection(options = {}) {
|
|
426
445
|
const manifests = loadInstallManifests(options);
|
|
427
|
-
const target = options.target
|
|
446
|
+
const target = options.target ? normalizeInstallTarget(options.target) : null;
|
|
428
447
|
|
|
429
448
|
if (target && !SUPPORTED_INSTALL_TARGETS.includes(target)) {
|
|
430
449
|
throw new Error(
|
|
@@ -508,7 +527,7 @@ function resolveInstallPlan(options = {}) {
|
|
|
508
527
|
}
|
|
509
528
|
}
|
|
510
529
|
|
|
511
|
-
const target = options.target
|
|
530
|
+
const target = options.target ? normalizeInstallTarget(options.target) : null;
|
|
512
531
|
if (target && !SUPPORTED_INSTALL_TARGETS.includes(target)) {
|
|
513
532
|
throw new Error(
|
|
514
533
|
`Unknown install target: ${target}. Expected one of ${SUPPORTED_INSTALL_TARGETS.join(', ')}`
|