@opengsd/gsd-core 1.5.0-rc.1 → 1.5.0-rc.2
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/.claude-plugin/plugin.json +1 -1
- package/agents/gsd-code-fixer.md +3 -2
- package/agents/gsd-debug-session-manager.md +2 -1
- package/agents/gsd-debugger.md +4 -3
- package/agents/gsd-executor.md +16 -15
- package/agents/gsd-intel-updater.md +38 -41
- package/agents/gsd-phase-researcher.md +8 -8
- package/agents/gsd-plan-checker.md +12 -11
- package/agents/gsd-planner.md +21 -181
- package/agents/gsd-project-researcher.md +5 -4
- package/agents/gsd-research-synthesizer.md +2 -1
- package/agents/gsd-ui-researcher.md +2 -1
- package/agents/gsd-verifier.md +9 -8
- package/bin/install.js +205 -1402
- package/gemini-extension.json +1 -1
- package/gsd-core/bin/gsd_run +20 -0
- package/gsd-core/bin/lib/capability-registry.cjs +1820 -3
- package/gsd-core/bin/lib/check-command-router.cjs +133 -2
- package/gsd-core/bin/lib/core.cjs +51 -1
- package/gsd-core/bin/lib/edge-probe.cjs +173 -0
- package/gsd-core/bin/lib/fallow-runner.cjs +63 -25
- package/gsd-core/bin/lib/intel.cjs +3 -3
- package/gsd-core/bin/lib/io.cjs +61 -6
- package/gsd-core/bin/lib/phase-command-router.cjs +20 -0
- package/gsd-core/bin/lib/phase.cjs +17 -0
- package/gsd-core/bin/lib/probe-core.cjs +257 -0
- package/gsd-core/bin/lib/roadmap.cjs +40 -0
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +51 -141
- package/gsd-core/bin/lib/runtime-config-adapter-registry.cjs +67 -29
- package/gsd-core/bin/lib/runtime-homes.cjs +137 -101
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +1439 -0
- package/gsd-core/bin/lib/runtime-name-policy.cjs +1 -1
- package/gsd-core/bin/lib/runtime-slash.cjs +7 -2
- package/gsd-core/bin/lib/state-document.cjs +8 -0
- package/gsd-core/bin/lib/uat-predicate.cjs +329 -0
- package/gsd-core/bin/lib/update-context.cjs +4 -1
- package/gsd-core/bin/lib/verify.cjs +103 -0
- package/gsd-core/bin/lib/worktree-base-ref.cjs +33 -8
- package/gsd-core/bin/shared/model-catalog.json +11 -6
- package/gsd-core/bin/shared/runtime-aliases.manifest.json +2 -1
- package/gsd-core/references/edge-probe-fixtures/01-round-half-even/expected-coverage.json +7 -0
- package/gsd-core/references/edge-probe-fixtures/01-round-half-even/requirements.json +1 -0
- package/gsd-core/references/edge-probe-fixtures/02-merge-intervals/expected-coverage.json +8 -0
- package/gsd-core/references/edge-probe-fixtures/02-merge-intervals/requirements.json +1 -0
- package/gsd-core/references/edge-probe-fixtures/03-truncate-graphemes/expected-coverage.json +7 -0
- package/gsd-core/references/edge-probe-fixtures/03-truncate-graphemes/requirements.json +1 -0
- package/gsd-core/references/edge-probe-fixtures/04-money-rounding/expected-coverage.json +7 -0
- package/gsd-core/references/edge-probe-fixtures/04-money-rounding/requirements.json +1 -0
- package/gsd-core/references/edge-probe-fixtures/05-list-dedupe/expected-coverage.json +8 -0
- package/gsd-core/references/edge-probe-fixtures/05-list-dedupe/requirements.json +1 -0
- package/gsd-core/references/edge-probe-fixtures/06-resolved-mixed/expected-coverage.json +8 -0
- package/gsd-core/references/edge-probe-fixtures/06-resolved-mixed/requirements.json +1 -0
- package/gsd-core/references/edge-probe-fixtures/06-resolved-mixed/resolutions.json +4 -0
- package/gsd-core/references/edge-probe.md +261 -0
- package/gsd-core/references/planner-antipatterns.md +41 -0
- package/gsd-core/references/planner-guidance.md +186 -0
- package/gsd-core/templates/spec.md +12 -0
- package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -1
- package/gsd-core/workflows/add-backlog.md +1 -1
- package/gsd-core/workflows/add-phase.md +1 -1
- package/gsd-core/workflows/add-tests.md +1 -1
- package/gsd-core/workflows/add-todo.md +1 -1
- package/gsd-core/workflows/ai-integration-phase.md +1 -1
- package/gsd-core/workflows/audit-fix.md +1 -1
- package/gsd-core/workflows/audit-milestone.md +1 -1
- package/gsd-core/workflows/audit-uat.md +1 -1
- package/gsd-core/workflows/autonomous.md +26 -37
- package/gsd-core/workflows/check-todos.md +1 -1
- package/gsd-core/workflows/cleanup.md +1 -1
- package/gsd-core/workflows/code-review-fix.md +1 -1
- package/gsd-core/workflows/code-review.md +51 -16
- package/gsd-core/workflows/complete-milestone.md +1 -1
- package/gsd-core/workflows/debug.md +1 -1
- package/gsd-core/workflows/diagnose-issues.md +1 -1
- package/gsd-core/workflows/discuss-phase/modes/advisor.md +1 -1
- package/gsd-core/workflows/discuss-phase/modes/auto.md +1 -1
- package/gsd-core/workflows/discuss-phase/modes/chain.md +1 -1
- package/gsd-core/workflows/discuss-phase-assumptions.md +1 -1
- package/gsd-core/workflows/discuss-phase.md +1 -1
- package/gsd-core/workflows/do.md +1 -1
- package/gsd-core/workflows/docs-update.md +1 -1
- package/gsd-core/workflows/edit-phase.md +1 -1
- package/gsd-core/workflows/eval-review.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +1 -1
- package/gsd-core/workflows/execute-phase.md +1 -1
- package/gsd-core/workflows/execute-plan.md +1 -1
- package/gsd-core/workflows/explore.md +1 -1
- package/gsd-core/workflows/extract-learnings.md +1 -1
- package/gsd-core/workflows/forensics.md +1 -1
- package/gsd-core/workflows/graduation.md +1 -1
- package/gsd-core/workflows/health.md +1 -1
- package/gsd-core/workflows/import.md +1 -1
- package/gsd-core/workflows/ingest-docs.md +1 -1
- package/gsd-core/workflows/insert-phase.md +1 -1
- package/gsd-core/workflows/list-workspaces.md +1 -1
- package/gsd-core/workflows/manager.md +1 -1
- package/gsd-core/workflows/map-codebase.md +1 -1
- package/gsd-core/workflows/milestone-summary.md +1 -1
- package/gsd-core/workflows/mvp-phase.md +1 -1
- package/gsd-core/workflows/new-milestone.md +9 -1
- package/gsd-core/workflows/new-project.md +9 -1
- package/gsd-core/workflows/new-workspace.md +1 -1
- package/gsd-core/workflows/next.md +1 -1
- package/gsd-core/workflows/pause-work.md +1 -1
- package/gsd-core/workflows/plan-milestone-gaps.md +1 -1
- package/gsd-core/workflows/plan-phase.md +39 -27
- package/gsd-core/workflows/plan-review-convergence.md +1 -1
- package/gsd-core/workflows/plant-seed.md +1 -1
- package/gsd-core/workflows/profile-user.md +1 -1
- package/gsd-core/workflows/progress.md +1 -1
- package/gsd-core/workflows/quick.md +1 -1
- package/gsd-core/workflows/remove-phase.md +1 -1
- package/gsd-core/workflows/remove-workspace.md +1 -1
- package/gsd-core/workflows/resume-project.md +1 -1
- package/gsd-core/workflows/review.md +1 -1
- package/gsd-core/workflows/scan.md +1 -1
- package/gsd-core/workflows/secure-phase.md +1 -1
- package/gsd-core/workflows/settings-advanced.md +18 -14
- package/gsd-core/workflows/settings-integrations.md +1 -1
- package/gsd-core/workflows/settings.md +2 -2
- package/gsd-core/workflows/ship.md +1 -1
- package/gsd-core/workflows/sketch-wrap-up.md +1 -1
- package/gsd-core/workflows/sketch.md +1 -1
- package/gsd-core/workflows/spec-phase.md +130 -1
- package/gsd-core/workflows/spike-wrap-up.md +1 -1
- package/gsd-core/workflows/spike.md +1 -1
- package/gsd-core/workflows/stats.md +1 -1
- package/gsd-core/workflows/thread.md +1 -1
- package/gsd-core/workflows/transition.md +1 -1
- package/gsd-core/workflows/ui-phase.md +1 -1
- package/gsd-core/workflows/ui-review.md +1 -1
- package/gsd-core/workflows/ultraplan-phase.md +1 -1
- package/gsd-core/workflows/update.md +2 -2
- package/gsd-core/workflows/validate-phase.md +1 -1
- package/gsd-core/workflows/verify-phase.md +1 -1
- package/gsd-core/workflows/verify-work.md +1 -1
- package/package.json +6 -3
- package/scripts/gen-capability-registry.cjs +498 -13
- package/scripts/lib/allowlist-ratchet.cjs +101 -1
- package/scripts/lint-test-file-count.allowlist.json +15 -2
- package/scripts/lint-windows-test-portability.cjs +178 -0
- package/scripts/research-profiles.cjs +10 -10
- package/scripts/run-tests.cjs +54 -13
- package/scripts/sync-next-version.cjs +133 -0
- package/scripts/sync-runtime-launcher.cjs +21 -5
- package/scripts/update-size-baseline.cjs +68 -0
- package/scripts/workflow-policy.cjs +42 -9
- package/scripts/workflow-size.cjs +90 -0
|
@@ -1,30 +1,39 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Runtime config adapter registry — dispatch table for install-phase config
|
|
4
|
+
* mutations (issue #60), replacing inline `runtime === '...'` branching in
|
|
5
|
+
* bin/install.js.
|
|
6
|
+
*
|
|
7
|
+
* ADR-857 phase 5g drive 2: The hand-kept REGISTRY const has been retired.
|
|
8
|
+
* Values are now read directly from the capability-registry.cjs descriptor
|
|
9
|
+
* (capabilities/<id>/capability.json runtime block) so a single source of
|
|
10
|
+
* truth drives all surfaces.
|
|
11
|
+
*
|
|
12
|
+
* Design notes:
|
|
13
|
+
* - `installSurface` selects which config handler install() runs:
|
|
14
|
+
* 'settings-json' → fall through to the shared settings.json accumulation.
|
|
15
|
+
* 'codex-toml' → early-return after writing codex.toml.
|
|
16
|
+
* 'copilot-instructions' → early-return after writing .github/copilot-instructions.md.
|
|
17
|
+
* 'cline-rules' → early-return after writing .clinerules.
|
|
18
|
+
* 'cursor-hooks-json' → early-return after writing .cursor/hooks.json (issue #777).
|
|
19
|
+
* 'profile-marker-only' → early-return after writing only the profile marker.
|
|
20
|
+
* - `writesSharedSettings` is the finishInstall writeSettings gate:
|
|
21
|
+
* false for codex / copilot / kilo / cursor / windsurf / trae / cline / kimi (legacy exclusion list).
|
|
22
|
+
* true for all other runtimes.
|
|
23
|
+
* - `finishPermissionWriter` names the finishInstall-phase dedicated config writer:
|
|
24
|
+
* 'opencode' → writes BOTH shared settings AND its own permissions file.
|
|
25
|
+
* 'kilo' → writes only its own permissions file.
|
|
26
|
+
* null → no dedicated permission writer.
|
|
27
|
+
*/
|
|
28
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
29
|
+
const { runtimes } = require('./capability-registry.cjs');
|
|
23
30
|
// ---------------------------------------------------------------------------
|
|
24
31
|
// Exports
|
|
25
32
|
// ---------------------------------------------------------------------------
|
|
26
33
|
/** The complete set of 16 supported runtimes for config-adapter dispatch. */
|
|
27
|
-
const ALLOWED_CONFIG_RUNTIMES = new Set(Object.
|
|
34
|
+
const ALLOWED_CONFIG_RUNTIMES = new Set(Object.entries(runtimes)
|
|
35
|
+
.filter(([, cap]) => cap && cap.runtime && typeof cap.runtime['installSurface'] === 'string')
|
|
36
|
+
.map(([id]) => id));
|
|
28
37
|
/** All valid installSurface values. */
|
|
29
38
|
const INSTALL_SURFACES = Object.freeze([
|
|
30
39
|
'settings-json',
|
|
@@ -43,15 +52,44 @@ const INSTALL_SURFACES = Object.freeze([
|
|
|
43
52
|
* @throws {TypeError} if runtime is not a known supported runtime.
|
|
44
53
|
*/
|
|
45
54
|
function resolveRuntimeConfigIntent(runtime) {
|
|
46
|
-
|
|
55
|
+
const entry = runtimes[runtime]?.runtime;
|
|
56
|
+
if (!entry)
|
|
47
57
|
throw new TypeError(`Unknown runtime for config adapter: ${runtime}`);
|
|
48
|
-
|
|
49
|
-
|
|
58
|
+
const permissionWriter = entry['permissionWriter'];
|
|
59
|
+
return {
|
|
60
|
+
runtime,
|
|
61
|
+
installSurface: entry['installSurface'],
|
|
62
|
+
writesSharedSettings: entry['writesSharedSettings'],
|
|
63
|
+
finishPermissionWriter: permissionWriter == null ? null : permissionWriter,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Resolve the complete install plan for a given runtime.
|
|
68
|
+
*
|
|
69
|
+
* Composes the config-intent axes from resolveRuntimeConfigIntent PLUS the
|
|
70
|
+
* three hook axes (hookEvents / extendedHookEvents / hooksSurface) that
|
|
71
|
+
* install() previously read scattered from the capability registry.
|
|
72
|
+
*
|
|
73
|
+
* ADR-857 phase 5g capstone — single typed seam for all install-level
|
|
74
|
+
* descriptor reads. Returns a fresh object each call.
|
|
75
|
+
*
|
|
76
|
+
* @throws {TypeError} if runtime is not a known supported runtime.
|
|
77
|
+
*/
|
|
78
|
+
function resolveInstallPlan(runtime) {
|
|
79
|
+
const desc = runtimes[runtime]?.runtime;
|
|
80
|
+
if (!desc)
|
|
81
|
+
throw new TypeError(`Unknown runtime for install plan: ${runtime}`);
|
|
82
|
+
const configIntent = resolveRuntimeConfigIntent(runtime);
|
|
50
83
|
return {
|
|
51
84
|
runtime,
|
|
52
|
-
installSurface:
|
|
53
|
-
writesSharedSettings:
|
|
54
|
-
finishPermissionWriter:
|
|
85
|
+
installSurface: configIntent.installSurface,
|
|
86
|
+
writesSharedSettings: configIntent.writesSharedSettings,
|
|
87
|
+
finishPermissionWriter: configIntent.finishPermissionWriter,
|
|
88
|
+
hookEvents: desc['hookEvents'],
|
|
89
|
+
extendedHookEvents: Array.isArray(desc['extendedHookEvents']) ? desc['extendedHookEvents'] : [],
|
|
90
|
+
hooksSurface: desc['hooksSurface'] != null
|
|
91
|
+
? desc['hooksSurface']
|
|
92
|
+
: ((runtime === 'opencode' || runtime === 'kilo') ? 'none' : 'settings-json'),
|
|
55
93
|
};
|
|
56
94
|
}
|
|
57
|
-
module.exports = { resolveRuntimeConfigIntent, ALLOWED_CONFIG_RUNTIMES, INSTALL_SURFACES };
|
|
95
|
+
module.exports = { resolveRuntimeConfigIntent, resolveInstallPlan, ALLOWED_CONFIG_RUNTIMES, INSTALL_SURFACES };
|
|
@@ -20,11 +20,21 @@
|
|
|
20
20
|
* with Kimi selecting the first existing generic skills directory.
|
|
21
21
|
* ~/.kimi-code/skills is brand-specific and can be selected as a
|
|
22
22
|
* GSD write target with --config-dir or KIMI_CONFIG_DIR.
|
|
23
|
+
* trae — Targets Trae IDE (trae.ai), the Electron-based IDE — NOT
|
|
24
|
+
* trae-agent (github.com/bytedance/trae-agent), a Python CLI that
|
|
25
|
+
* uses trae_config.yaml, has no ~/.trae directory, and has no
|
|
26
|
+
* skills system. Both are ByteDance "Trae" products; they are
|
|
27
|
+
* entirely distinct. The global ~/.trae/skills/ path is
|
|
28
|
+
* community-soft-confirmed: docs.trae.ai/ide/skills documents the
|
|
29
|
+
* SKILL.md format and project-level .trae/skills/, but does NOT
|
|
30
|
+
* publish the global on-disk path; ~/.trae/skills/ rests on
|
|
31
|
+
* community evidence incl. Trae-AI/TRAE#2253. Best-effort only.
|
|
23
32
|
*/
|
|
24
33
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
25
34
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
26
35
|
};
|
|
27
36
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
exports.resolveConfigHomeFromDescriptor = resolveConfigHomeFromDescriptor;
|
|
28
38
|
exports.resolveAntigravityGlobalDir = resolveAntigravityGlobalDir;
|
|
29
39
|
exports.resolveKimiGlobalDir = resolveKimiGlobalDir;
|
|
30
40
|
exports.getGlobalConfigDir = getGlobalConfigDir;
|
|
@@ -44,26 +54,112 @@ function expandTilde(p) {
|
|
|
44
54
|
return node_path_1.default.join(node_os_1.default.homedir(), p.slice(1));
|
|
45
55
|
return p;
|
|
46
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Resolve a configHome descriptor to an absolute directory path.
|
|
59
|
+
*
|
|
60
|
+
* Implements the four descriptor kinds:
|
|
61
|
+
* - dot-home: env-override → path.join(home, name)
|
|
62
|
+
* - dot-home-nested: env-override → probed subdir of path.join(home, parent)
|
|
63
|
+
* - xdg: env[0] → env[1](dirname) → env[2](XDG subdir) → ~/.config/<name>
|
|
64
|
+
* - generic-agents-root:env[0] → first probe where probeExists exists → probe[0]
|
|
65
|
+
*/
|
|
66
|
+
function resolveConfigHomeFromDescriptor(configHome, opts = {}) {
|
|
67
|
+
const env = opts.env ?? process.env;
|
|
68
|
+
const home = opts.home ?? node_os_1.default.homedir();
|
|
69
|
+
const existsSyncFn = opts.existsSync ?? node_fs_1.default.existsSync;
|
|
70
|
+
switch (configHome.kind) {
|
|
71
|
+
case 'dot-home': {
|
|
72
|
+
// First env var that is set wins
|
|
73
|
+
for (const varName of configHome.env) {
|
|
74
|
+
const val = env[varName];
|
|
75
|
+
if (val)
|
|
76
|
+
return expandTilde(val);
|
|
77
|
+
}
|
|
78
|
+
return node_path_1.default.join(home, configHome.name);
|
|
79
|
+
}
|
|
80
|
+
case 'dot-home-nested': {
|
|
81
|
+
// env override
|
|
82
|
+
const nestedEnv0Val = env[configHome.env[0]];
|
|
83
|
+
if (configHome.env[0] && nestedEnv0Val) {
|
|
84
|
+
return expandTilde(nestedEnv0Val);
|
|
85
|
+
}
|
|
86
|
+
const base = node_path_1.default.join(home, configHome.parent);
|
|
87
|
+
if (configHome.probe && configHome.probe.length > 0) {
|
|
88
|
+
// probe each candidate under base; return first that exists
|
|
89
|
+
for (const candidate of configHome.probe) {
|
|
90
|
+
const resolved = node_path_1.default.join(base, candidate);
|
|
91
|
+
if (existsSyncFn(resolved))
|
|
92
|
+
return resolved;
|
|
93
|
+
}
|
|
94
|
+
// fallback: first probe candidate
|
|
95
|
+
return node_path_1.default.join(base, configHome.probe[0]);
|
|
96
|
+
}
|
|
97
|
+
// no probe (e.g. windsurf): always name under parent
|
|
98
|
+
return node_path_1.default.join(base, configHome.name);
|
|
99
|
+
}
|
|
100
|
+
case 'xdg': {
|
|
101
|
+
// env[0]: direct override dir
|
|
102
|
+
const xdgEnv0Val = env[configHome.env[0]];
|
|
103
|
+
if (configHome.env[0] && xdgEnv0Val) {
|
|
104
|
+
return expandTilde(xdgEnv0Val);
|
|
105
|
+
}
|
|
106
|
+
// env[1]: FILE path → dirname
|
|
107
|
+
const xdgEnv1Val = env[configHome.env[1]];
|
|
108
|
+
if (configHome.env[1] && xdgEnv1Val) {
|
|
109
|
+
return node_path_1.default.dirname(expandTilde(xdgEnv1Val));
|
|
110
|
+
}
|
|
111
|
+
// env[2]: XDG_CONFIG_HOME → subdir
|
|
112
|
+
const xdgEnv2Val = env[configHome.env[2]];
|
|
113
|
+
if (configHome.env[2] && xdgEnv2Val) {
|
|
114
|
+
return node_path_1.default.join(expandTilde(xdgEnv2Val), configHome.name);
|
|
115
|
+
}
|
|
116
|
+
return node_path_1.default.join(home, '.config', configHome.name);
|
|
117
|
+
}
|
|
118
|
+
case 'generic-agents-root': {
|
|
119
|
+
// env override
|
|
120
|
+
const garEnv0Val = env[configHome.env[0]];
|
|
121
|
+
if (configHome.env[0] && garEnv0Val) {
|
|
122
|
+
return expandTilde(garEnv0Val);
|
|
123
|
+
}
|
|
124
|
+
// probe each candidate; return first where probeExists subpath exists
|
|
125
|
+
for (const candidate of configHome.probe) {
|
|
126
|
+
const resolved = expandTildeWithHome(candidate, home);
|
|
127
|
+
if (existsSyncFn(node_path_1.default.join(resolved, configHome.probeExists))) {
|
|
128
|
+
return resolved;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// fallback: first probe candidate
|
|
132
|
+
return expandTildeWithHome(configHome.probe[0], home);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Expand ~ using an explicit home directory (for hermetic testing).
|
|
138
|
+
*/
|
|
139
|
+
function expandTildeWithHome(p, home) {
|
|
140
|
+
if (!p)
|
|
141
|
+
return p;
|
|
142
|
+
if (p.startsWith('~/') || p === '~')
|
|
143
|
+
return node_path_1.default.join(home, p.slice(1));
|
|
144
|
+
return p;
|
|
145
|
+
}
|
|
47
146
|
/**
|
|
48
147
|
* Resolve Antigravity global config dir across 1.x and 2.x layouts.
|
|
148
|
+
*
|
|
149
|
+
* Thin wrapper delegating to resolveConfigHomeFromDescriptor with the
|
|
150
|
+
* antigravity descriptor shape. Preserved for external callers and tests.
|
|
49
151
|
*/
|
|
50
152
|
function resolveAntigravityGlobalDir(opts = {}) {
|
|
51
153
|
const env = opts.env ?? process.env;
|
|
52
154
|
const home = opts.home ?? node_os_1.default.homedir();
|
|
53
155
|
const existsSyncFn = opts.existsSync ?? node_fs_1.default.existsSync;
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
];
|
|
62
|
-
for (const candidate of candidates) {
|
|
63
|
-
if (existsSyncFn(candidate))
|
|
64
|
-
return candidate;
|
|
65
|
-
}
|
|
66
|
-
return node_path_1.default.join(base, 'antigravity');
|
|
156
|
+
return resolveConfigHomeFromDescriptor({
|
|
157
|
+
kind: 'dot-home-nested',
|
|
158
|
+
name: 'antigravity',
|
|
159
|
+
parent: '.gemini',
|
|
160
|
+
env: ['ANTIGRAVITY_CONFIG_DIR'],
|
|
161
|
+
probe: ['antigravity', 'antigravity-ide', 'antigravity-cli'],
|
|
162
|
+
}, { env, home, existsSync: existsSyncFn });
|
|
67
163
|
}
|
|
68
164
|
/**
|
|
69
165
|
* Resolve Kimi's generic user root using Kimi CLI's documented first-existing
|
|
@@ -79,21 +175,21 @@ function resolveAntigravityGlobalDir(opts = {}) {
|
|
|
79
175
|
* KIMI_CONFIG_DIR is a GSD installer write-location override. It is not Kimi's
|
|
80
176
|
* upstream data-root variable, and arbitrary roots are discoverable by Kimi only
|
|
81
177
|
* when the user also configures Kimi --skills-dir or extra_skill_dirs.
|
|
178
|
+
*
|
|
179
|
+
* Thin wrapper delegating to resolveConfigHomeFromDescriptor with the
|
|
180
|
+
* kimi descriptor shape. Preserved for external callers and tests.
|
|
82
181
|
*/
|
|
83
182
|
function resolveKimiGlobalDir(opts = {}) {
|
|
84
183
|
const env = opts.env ?? process.env;
|
|
85
184
|
const home = opts.home ?? node_os_1.default.homedir();
|
|
86
185
|
const existsSyncFn = opts.existsSync ?? node_fs_1.default.existsSync;
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
return candidate;
|
|
95
|
-
}
|
|
96
|
-
return recommendedRoot;
|
|
186
|
+
return resolveConfigHomeFromDescriptor({
|
|
187
|
+
kind: 'generic-agents-root',
|
|
188
|
+
name: 'agents',
|
|
189
|
+
env: ['KIMI_CONFIG_DIR'],
|
|
190
|
+
probe: ['~/.config/agents', '~/.agents'],
|
|
191
|
+
probeExists: 'skills',
|
|
192
|
+
}, { env, home, existsSync: existsSyncFn });
|
|
97
193
|
}
|
|
98
194
|
/**
|
|
99
195
|
* Return the global config base directory for the given runtime.
|
|
@@ -107,85 +203,25 @@ function resolveKimiGlobalDir(opts = {}) {
|
|
|
107
203
|
function getGlobalConfigDir(runtime, explicitDir) {
|
|
108
204
|
if (explicitDir)
|
|
109
205
|
return expandTilde(explicitDir);
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
// ── Grok Build ───────────────────────────────────────────────────────────
|
|
126
|
-
case 'grok':
|
|
127
|
-
return env['GROK_AGENTS_HOME'] ? expandTilde(env['GROK_AGENTS_HOME']) : node_path_1.default.join(home, '.agents');
|
|
128
|
-
// ── Copilot (VS Code) ────────────────────────────────────────────────────
|
|
129
|
-
case 'copilot':
|
|
130
|
-
if (env['COPILOT_CONFIG_DIR'])
|
|
131
|
-
return expandTilde(env['COPILOT_CONFIG_DIR']);
|
|
132
|
-
if (env['COPILOT_HOME'])
|
|
133
|
-
return expandTilde(env['COPILOT_HOME']);
|
|
134
|
-
return node_path_1.default.join(home, '.copilot');
|
|
135
|
-
// ── Antigravity ──────────────────────────────────────────────────────────
|
|
136
|
-
case 'antigravity':
|
|
137
|
-
return resolveAntigravityGlobalDir({ env, home });
|
|
138
|
-
// ── Windsurf ─────────────────────────────────────────────────────────────
|
|
139
|
-
case 'windsurf':
|
|
140
|
-
return env['WINDSURF_CONFIG_DIR']
|
|
141
|
-
? expandTilde(env['WINDSURF_CONFIG_DIR'])
|
|
142
|
-
: node_path_1.default.join(home, '.codeium', 'windsurf');
|
|
143
|
-
// ── Augment ──────────────────────────────────────────────────────────────
|
|
144
|
-
case 'augment':
|
|
145
|
-
return env['AUGMENT_CONFIG_DIR'] ? expandTilde(env['AUGMENT_CONFIG_DIR']) : node_path_1.default.join(home, '.augment');
|
|
146
|
-
// ── Trae ─────────────────────────────────────────────────────────────────
|
|
147
|
-
case 'trae':
|
|
148
|
-
return env['TRAE_CONFIG_DIR'] ? expandTilde(env['TRAE_CONFIG_DIR']) : node_path_1.default.join(home, '.trae');
|
|
149
|
-
// ── Qwen Code ────────────────────────────────────────────────────────────
|
|
150
|
-
case 'qwen':
|
|
151
|
-
return env['QWEN_CONFIG_DIR'] ? expandTilde(env['QWEN_CONFIG_DIR']) : node_path_1.default.join(home, '.qwen');
|
|
152
|
-
// ── Hermes Agent ─────────────────────────────────────────────────────────
|
|
153
|
-
case 'hermes':
|
|
154
|
-
return env['HERMES_HOME'] ? expandTilde(env['HERMES_HOME']) : node_path_1.default.join(home, '.hermes');
|
|
155
|
-
// ── CodeBuddy ────────────────────────────────────────────────────────────
|
|
156
|
-
case 'codebuddy':
|
|
157
|
-
return env['CODEBUDDY_CONFIG_DIR'] ? expandTilde(env['CODEBUDDY_CONFIG_DIR']) : node_path_1.default.join(home, '.codebuddy');
|
|
158
|
-
// ── Cline ────────────────────────────────────────────────────────────────
|
|
159
|
-
case 'cline':
|
|
160
|
-
return env['CLINE_CONFIG_DIR'] ? expandTilde(env['CLINE_CONFIG_DIR']) : node_path_1.default.join(home, '.cline');
|
|
161
|
-
// ── Kimi CLI (generic agents user root) ────────────────────────────────
|
|
162
|
-
case 'kimi': {
|
|
163
|
-
return resolveKimiGlobalDir({ env, home });
|
|
164
|
-
}
|
|
165
|
-
// ── OpenCode (XDG) ───────────────────────────────────────────────────────
|
|
166
|
-
case 'opencode': {
|
|
167
|
-
if (env['OPENCODE_CONFIG_DIR'])
|
|
168
|
-
return expandTilde(env['OPENCODE_CONFIG_DIR']);
|
|
169
|
-
if (env['OPENCODE_CONFIG'])
|
|
170
|
-
return node_path_1.default.dirname(expandTilde(env['OPENCODE_CONFIG']));
|
|
171
|
-
if (env['XDG_CONFIG_HOME'])
|
|
172
|
-
return node_path_1.default.join(expandTilde(env['XDG_CONFIG_HOME']), 'opencode');
|
|
173
|
-
return node_path_1.default.join(home, '.config', 'opencode');
|
|
174
|
-
}
|
|
175
|
-
// ── Kilo (XDG) ───────────────────────────────────────────────────────────
|
|
176
|
-
case 'kilo': {
|
|
177
|
-
if (env['KILO_CONFIG_DIR'])
|
|
178
|
-
return expandTilde(env['KILO_CONFIG_DIR']);
|
|
179
|
-
if (env['KILO_CONFIG'])
|
|
180
|
-
return node_path_1.default.dirname(expandTilde(env['KILO_CONFIG']));
|
|
181
|
-
if (env['XDG_CONFIG_HOME'])
|
|
182
|
-
return node_path_1.default.join(expandTilde(env['XDG_CONFIG_HOME']), 'kilo');
|
|
183
|
-
return node_path_1.default.join(home, '.config', 'kilo');
|
|
184
|
-
}
|
|
185
|
-
// ── Default (Claude fallback) ─────────────────────────────────────────────
|
|
186
|
-
default:
|
|
187
|
-
return env['CLAUDE_CONFIG_DIR'] ? expandTilde(env['CLAUDE_CONFIG_DIR']) : node_path_1.default.join(home, '.claude');
|
|
206
|
+
// ── Grok: not in the registry — hardcoded branch ─────────────────────────
|
|
207
|
+
if (runtime === 'grok') {
|
|
208
|
+
const env = process.env;
|
|
209
|
+
return env['GROK_AGENTS_HOME'] ? expandTilde(env['GROK_AGENTS_HOME']) : node_path_1.default.join(node_os_1.default.homedir(), '.agents');
|
|
210
|
+
}
|
|
211
|
+
// ── Descriptor-driven: look up in capability-registry ────────────────────
|
|
212
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
213
|
+
const { runtimes } = require('./capability-registry.cjs');
|
|
214
|
+
const runtimeEntry = runtimes[runtime];
|
|
215
|
+
if (runtimeEntry?.runtime?.configHome) {
|
|
216
|
+
return resolveConfigHomeFromDescriptor(runtimeEntry.runtime.configHome, {
|
|
217
|
+
env: process.env,
|
|
218
|
+
home: node_os_1.default.homedir(),
|
|
219
|
+
existsSync: node_fs_1.default.existsSync,
|
|
220
|
+
});
|
|
188
221
|
}
|
|
222
|
+
// ── Default (unknown runtime → Claude fallback) ───────────────────────────
|
|
223
|
+
const env = process.env;
|
|
224
|
+
return env['CLAUDE_CONFIG_DIR'] ? expandTilde(env['CLAUDE_CONFIG_DIR']) : node_path_1.default.join(node_os_1.default.homedir(), '.claude');
|
|
189
225
|
}
|
|
190
226
|
/**
|
|
191
227
|
* Return the global skills base directory for the given runtime.
|