dsh-gitbash-shell 0.34.3 → 0.35.1
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/CHANGELOG.md +21 -0
- package/README.md +38 -15
- package/README_EN.md +29 -8
- package/dsh.plugin.json +2 -2
- package/package.json +4 -1
- package/src/client.js +170 -0
- package/src/fastctx-bridge.js +378 -0
- package/src/index.js +229 -8
- package/src/inline-tools.js +434 -0
package/src/index.js
CHANGED
|
@@ -56,6 +56,8 @@ import { fileURLToPath } from 'node:url'
|
|
|
56
56
|
|
|
57
57
|
import { PRESET_META, minimalPluginsFor, pluginsFor } from './compositions.js'
|
|
58
58
|
import { loadSchemastery } from './schemastery.js'
|
|
59
|
+
import { GITBASH_MSYS_ADDENDUM, GITBASH_ROUTE_ADDENDUM, mountInlineTools, resolveHostPwsh7 } from './inline-tools.js'
|
|
60
|
+
import { mountFastctx } from './fastctx-bridge.js'
|
|
59
61
|
|
|
60
62
|
/**
|
|
61
63
|
* The executor base class's own Config schema, when this deployment has it.
|
|
@@ -119,6 +121,21 @@ const MARKER_FILE = '.plugin-managed.json'
|
|
|
119
121
|
/** Default preset ids this plugin materializes, in roster order (configurable). */
|
|
120
122
|
export const PRESET_IDS = ['standard-gitbash', 'minimal-gitbash', 'code-gitbash', 'cordis-gitbash']
|
|
121
123
|
|
|
124
|
+
/**
|
|
125
|
+
* Variant preset id -> the OFFICIAL successor id, for the deployment-default
|
|
126
|
+
* migration (v0.35.0). Every target is verified against the LIVE roster
|
|
127
|
+
* before any write — the official ids renamed once already (code→ptc), so a
|
|
128
|
+
* missing successor stands the migration down instead of writing an unknown
|
|
129
|
+
* id. `code-gitbash` deliberately maps to `ptc`: that variant has described
|
|
130
|
+
* the official PTC mode since dsh 0.1.2 renamed it.
|
|
131
|
+
*/
|
|
132
|
+
export const VARIANT_DEFAULT_SUCCESSORS = Object.freeze({
|
|
133
|
+
'standard-gitbash': 'standard',
|
|
134
|
+
'minimal-gitbash': 'minimal',
|
|
135
|
+
'code-gitbash': 'ptc',
|
|
136
|
+
'cordis-gitbash': 'cordis',
|
|
137
|
+
})
|
|
138
|
+
|
|
122
139
|
/**
|
|
123
140
|
* The variant dsh-ptc-cordis-preset already covers while cooperating: its
|
|
124
141
|
* `PTC 创造模式` is materialized against Git Bash too, so our own
|
|
@@ -474,6 +491,30 @@ export const Config = Schema === null ? undefined : Schema.object({
|
|
|
474
491
|
* changing it on either side changes it here.
|
|
475
492
|
*/
|
|
476
493
|
suppressPeerCordis: live(Schema.boolean().default(false)),
|
|
494
|
+
/**
|
|
495
|
+
* Serve the four `* · Git Bash` VARIANT presets (v0.34.x behaviour) instead
|
|
496
|
+
* of relying on the inline tool patch (v0.35.0). Default OFF for every user
|
|
497
|
+
* — new and existing — per the owner's explicit call: the official presets
|
|
498
|
+
* carry Git Bash through the per-agent tool patch, the roster stays the
|
|
499
|
+
* official four, and the variants remain one switch away for anyone who
|
|
500
|
+
* wants the duplicated roster back. OFF also stops the reconcile from
|
|
501
|
+
* registering variants; a session pinned to a variant id must re-select an
|
|
502
|
+
* official preset (the roster flip is announced in the CHANGELOG).
|
|
503
|
+
*/
|
|
504
|
+
variantPresets: live(Schema.boolean().default(false)),
|
|
505
|
+
/**
|
|
506
|
+
* Publish `gitbash_pwsh` — a REAL PowerShell 7 tool over ctx.subprocess —
|
|
507
|
+
* while the host `pwsh` tool is denied (its executor is Git Bash on this
|
|
508
|
+
* host). Default ON; requires pwsh 7 on the machine (never a bundled
|
|
509
|
+
* payload) and danger-full-access per session.
|
|
510
|
+
*/
|
|
511
|
+
pwshTool: live(Schema.boolean().default(true)),
|
|
512
|
+
/**
|
|
513
|
+
* Publish the FastCtx file tools (`gb_*`) through the local MCP bridge.
|
|
514
|
+
* Default ON; Windows-only payload, stands down entirely when dsh-ops is
|
|
515
|
+
* present (its ops_* tools already cover the same ground).
|
|
516
|
+
*/
|
|
517
|
+
fastctxTools: live(Schema.boolean().default(true)),
|
|
477
518
|
})
|
|
478
519
|
|
|
479
520
|
/** Read one Config value across eras: Volatile ref (>= 0.1.7) or plain value. */
|
|
@@ -533,6 +574,13 @@ function makeLiveReader(ctx, config) {
|
|
|
533
574
|
adoptSidebar: valueOf(config.adoptSidebar) !== false,
|
|
534
575
|
// Default ON (v0.29.0): the official terminal is ours unless opted out.
|
|
535
576
|
autoTerminalShell: valueOf(config.autoTerminalShell) !== false,
|
|
577
|
+
// Default OFF (v0.35.0): the official presets carry Git Bash through the
|
|
578
|
+
// inline tool patch; the variant roster is opt-in.
|
|
579
|
+
variantPresets: valueOf(config.variantPresets) === true,
|
|
580
|
+
// Default ON (v0.35.0): the pwsh replacement fills the denied host tool.
|
|
581
|
+
pwshTool: valueOf(config.pwshTool) !== false,
|
|
582
|
+
// Default ON (v0.35.0): the FastCtx bridge stands down when dsh-ops is present.
|
|
583
|
+
fastctxTools: valueOf(config.fastctxTools) !== false,
|
|
536
584
|
}
|
|
537
585
|
}
|
|
538
586
|
return {
|
|
@@ -540,6 +588,9 @@ function makeLiveReader(ctx, config) {
|
|
|
540
588
|
posix: () => dialect().posixPaths === true,
|
|
541
589
|
adoptSidebar: () => dialect().adoptSidebar !== false,
|
|
542
590
|
autoTerminalShell: () => dialect().autoTerminalShell !== false,
|
|
591
|
+
variantPresets: () => (hasConfig ? valueOf(config.variantPresets) === true : false),
|
|
592
|
+
pwshTool: () => (hasConfig ? valueOf(config.pwshTool) !== false : true),
|
|
593
|
+
fastctxTools: () => (hasConfig ? valueOf(config.fastctxTools) !== false : true),
|
|
543
594
|
// Default OFF: only an explicit true asks for deduplication.
|
|
544
595
|
suppressPeerCordis: () => (hasConfig ? valueOf(config.suppressPeerCordis) === true : false),
|
|
545
596
|
}
|
|
@@ -1742,7 +1793,7 @@ async function registerVariant(ctx, presetId, { gitBashActive, skillsDir, python
|
|
|
1742
1793
|
* variant's PTY row reads it once per registration (issue #15).
|
|
1743
1794
|
* @returns {Promise<void>} resolves once the first reconcile finished.
|
|
1744
1795
|
*/
|
|
1745
|
-
async function runDeclarativeEra(ctx, presetIds, readSuppress, readBashResolution) {
|
|
1796
|
+
async function runDeclarativeEra(ctx, presetIds, readSuppress, readBashResolution, readVariants) {
|
|
1746
1797
|
cleanupLegacyTrees(presetIds)
|
|
1747
1798
|
const gitBashActive = process.platform === 'win32'
|
|
1748
1799
|
const skillsDir = await resolveSkillsDir()
|
|
@@ -1758,7 +1809,12 @@ async function runDeclarativeEra(ctx, presetIds, readSuppress, readBashResolutio
|
|
|
1758
1809
|
let registeredPython = false
|
|
1759
1810
|
let serial = Promise.resolve()
|
|
1760
1811
|
|
|
1761
|
-
|
|
1812
|
+
// v0.35.0: the variant roster is opt-in (`variantPresets`, default OFF).
|
|
1813
|
+
// OFF means an EMPTY desired set — the cleanup above still runs, so a
|
|
1814
|
+
// legacy materialized tree never survives just because the switch is off.
|
|
1815
|
+
const desired = () => (readVariants && readVariants() === true
|
|
1816
|
+
? effectivePresetIds(presetIds, { suppress: readSuppress(), peerGitBash })
|
|
1817
|
+
: [])
|
|
1762
1818
|
|
|
1763
1819
|
const reconcile = () => {
|
|
1764
1820
|
serial = serial.then(async () => {
|
|
@@ -1811,7 +1867,10 @@ async function runDeclarativeEra(ctx, presetIds, readSuppress, readBashResolutio
|
|
|
1811
1867
|
}
|
|
1812
1868
|
|
|
1813
1869
|
await reconcile()
|
|
1814
|
-
console.log(TAG + ' registered ' + live.size + ' preset(s) declaratively (' + [...live.keys()].join(', ') + ')'
|
|
1870
|
+
console.log(TAG + ' registered ' + live.size + ' preset(s) declaratively (' + [...live.keys()].join(', ') + ')'
|
|
1871
|
+
+ (live.size === 0 ? ' — variantPresets is off: the official presets carry Git Bash through the inline tool patch (see the CHANGELOG)'
|
|
1872
|
+
: '')
|
|
1873
|
+
+ (hostExtras.timeContext || hostExtras.toolSchedule
|
|
1815
1874
|
? ' [dsh 0.2.1 additions: ' + (hostExtras.timeContext ? 'time-context' : '') + (hostExtras.timeContext && hostExtras.toolSchedule ? ' + ' : '') + (hostExtras.toolSchedule ? 'tool-schedule (subagents denied)' : '') + ']'
|
|
1816
1875
|
: ''))
|
|
1817
1876
|
|
|
@@ -1854,12 +1913,13 @@ async function runDeclarativeEra(ctx, presetIds, readSuppress, readBashResolutio
|
|
|
1854
1913
|
console.log(TAG + ' peer capability wiring failed: ' + (error && error.message ? error.message : error))
|
|
1855
1914
|
}
|
|
1856
1915
|
|
|
1857
|
-
// The
|
|
1858
|
-
// loader/volatile-update event on this fiber.
|
|
1916
|
+
// The switches themselves: a volatile Config edit on this row lands as a
|
|
1917
|
+
// loader/volatile-update event on this fiber (v0.35.0 adds variantPresets).
|
|
1859
1918
|
try {
|
|
1860
1919
|
ctx.on('loader/volatile-update', (paths) => {
|
|
1861
1920
|
try {
|
|
1862
|
-
if (!Array.isArray(paths) || !paths.some((path) => Array.isArray(path)
|
|
1921
|
+
if (!Array.isArray(paths) || !paths.some((path) => Array.isArray(path)
|
|
1922
|
+
&& (path[0] === 'suppressPeerCordis' || path[0] === 'variantPresets'))) return
|
|
1863
1923
|
void reconcile()
|
|
1864
1924
|
} catch (error) {
|
|
1865
1925
|
console.log(TAG + ' dedupe switch handling failed: ' + (error && error.message ? error.message : error))
|
|
@@ -1921,7 +1981,17 @@ export async function apply(ctx, config = {}) {
|
|
|
1921
1981
|
const readConfiguredBashPath = () => effectiveConfiguredBashPath(executorConfiguredBashPath(ctx), rowBashPath(config))
|
|
1922
1982
|
const readBashResolution = () => resolveGitBashCached({ configured: readConfiguredBashPath() })
|
|
1923
1983
|
const gitBashCapability = {
|
|
1984
|
+
// v0.35.0 semantics, unchanged shape: `active` answers "does command
|
|
1985
|
+
// execution run on Git Bash on this host" — TRUE regardless of the
|
|
1986
|
+
// variantPresets switch, because the inline tool patch carries the
|
|
1987
|
+
// official presets too. Peers (dsh-ptc-cordis-preset) key their roster
|
|
1988
|
+
// wording and dedupe on exactly this fact.
|
|
1924
1989
|
active: process.platform === 'win32',
|
|
1990
|
+
// Additive (v0.35.1): the inline tool patch gives EVERY OFFICIAL preset
|
|
1991
|
+
// Git Bash, so a roster suffix like "· Git Bash" no longer distinguishes
|
|
1992
|
+
// anything — peers reading this flag drop the suffix (dsh-ptc-cordis-preset
|
|
1993
|
+
// v0.17.3+); older peers ignore it and keep the v0.34 wording.
|
|
1994
|
+
get inlinePatched() { return process.platform === 'win32' },
|
|
1925
1995
|
// Kept for existing consumers (peer plugins read `bashPath`): the resolved
|
|
1926
1996
|
// interpreter. When resolution failed we report the explicit value (or the
|
|
1927
1997
|
// historical default) so the ENOENT a consumer may hit names a real path —
|
|
@@ -2015,6 +2085,21 @@ export async function apply(ctx, config = {}) {
|
|
|
2015
2085
|
no run_code hint — so they meet the shell they were composed for. */
|
|
2016
2086
|
const dialect = liveSettings.dialect()
|
|
2017
2087
|
const applies = dialectApplies(dialect, assembleContext && assembleContext.agent)
|
|
2088
|
+
// v0.35.0: shell-routing addendum on the `bash` tool's description.
|
|
2089
|
+
// Description is schema-level text, so even the minimal preset's
|
|
2090
|
+
// complete-persona cannot strip it; the ROUTING sentence applies to
|
|
2091
|
+
// every agent (routing is dialect-independent), while the MSYS
|
|
2092
|
+
// sentence only describes the world the dialect switch creates.
|
|
2093
|
+
// Idempotent by marker: assemble may run more than once per agent.
|
|
2094
|
+
if (assembly && typeof assembly === 'object' && Array.isArray(assembly.tools)) {
|
|
2095
|
+
for (const tool of assembly.tools) {
|
|
2096
|
+
if (tool && tool.name === 'bash' && typeof tool.description === 'string'
|
|
2097
|
+
&& !tool.description.includes('Prefer this bash tool')) {
|
|
2098
|
+
tool.description += '\n' + GITBASH_ROUTE_ADDENDUM
|
|
2099
|
+
+ (applies && dialect.posixPaths === true ? '\n' + GITBASH_MSYS_ADDENDUM : '')
|
|
2100
|
+
}
|
|
2101
|
+
}
|
|
2102
|
+
}
|
|
2018
2103
|
if (applies && dialect.posixPaths === true && assembly && typeof assembly === 'object') {
|
|
2019
2104
|
for (const section of Array.isArray(assembly.sections) ? assembly.sections : []) {
|
|
2020
2105
|
if (section && typeof section.text === 'string') section.text = windowsToMsys(section.text)
|
|
@@ -2509,13 +2594,149 @@ export async function apply(ctx, config = {}) {
|
|
|
2509
2594
|
})
|
|
2510
2595
|
}
|
|
2511
2596
|
|
|
2597
|
+
// ── inline tool patch (v0.35.0): Git Bash for the OFFICIAL presets ──────
|
|
2598
|
+
// The official preset rows compose `tool-bash` as win32-disabled, and the
|
|
2599
|
+
// patch layer cannot reach rows nested in a preset declaration (buildMap
|
|
2600
|
+
// only descends into group rows), so the fix runs at the tool layer: per
|
|
2601
|
+
// agent, a face of "pwsh yes / bash no" gets the OFFICIAL tool-bash
|
|
2602
|
+
// activated in an agent-owned scope plus a deny on the fake pwsh (its
|
|
2603
|
+
// executor is ctx.shell, which here IS Git Bash), and the assemble
|
|
2604
|
+
// waterfall carries the bash-first routing sentence. The variantPresets
|
|
2605
|
+
// switch is honored BY OBSERVATION — a variant agent's face already has
|
|
2606
|
+
// bash, so this patch never fires there.
|
|
2607
|
+
if (process.platform === 'win32') {
|
|
2608
|
+
try {
|
|
2609
|
+
mountInlineTools(ctx, {
|
|
2610
|
+
tools: (c) => { try { return c.get('tools') } catch { return undefined } },
|
|
2611
|
+
createScope: (agentCtx) => {
|
|
2612
|
+
let childCtx
|
|
2613
|
+
const fiber = agentCtx.plugin((c) => { childCtx = c })
|
|
2614
|
+
return {
|
|
2615
|
+
ctx: childCtx,
|
|
2616
|
+
dispose: async () => { try { await fiber?.dispose?.() } catch { /* already gone */ } },
|
|
2617
|
+
}
|
|
2618
|
+
},
|
|
2619
|
+
allowed: (session) => {
|
|
2620
|
+
try { return ctx.get('sandboxPolicy')?.resolve({ session })?.mode === 'danger-full-access' } catch { return false }
|
|
2621
|
+
},
|
|
2622
|
+
spawn: (spec) => {
|
|
2623
|
+
const subprocess = ctx.get('subprocess')
|
|
2624
|
+
if (!subprocess || typeof subprocess.spawn !== 'function') throw new Error('the host subprocess service is not available on this deployment')
|
|
2625
|
+
return subprocess.spawn(spec)
|
|
2626
|
+
},
|
|
2627
|
+
pwshPath: resolveHostPwsh7(),
|
|
2628
|
+
pwshEnabled: () => liveSettings.pwshTool(),
|
|
2629
|
+
msysToWin: (p) => translateMsysPath(p, buildTranslateEnv(readConfiguredBashPath())),
|
|
2630
|
+
echo: (text) => (liveSettings.dialect().posixPaths === true ? windowsToMsys(text) : text),
|
|
2631
|
+
log: (m) => console.log(TAG + ' ' + m),
|
|
2632
|
+
})
|
|
2633
|
+
console.log(TAG + ' inline tool patch armed (official presets get Git Bash; bash-first routing enforced)')
|
|
2634
|
+
} catch (error) {
|
|
2635
|
+
console.log(TAG + ' inline tool patch wiring failed: ' + (error?.message ?? error))
|
|
2636
|
+
}
|
|
2637
|
+
}
|
|
2638
|
+
|
|
2639
|
+
// ── default-preset migration (v0.35.0, user request) ─────────────────────
|
|
2640
|
+
// A session records its preset by ID (`agent-preset/selected`), and the
|
|
2641
|
+
// registry resolves EVERY mount through `definitions.get(id)` — a variant
|
|
2642
|
+
// id that is not registered fails `agent-preset/not-found`, and the
|
|
2643
|
+
// official `select` refuses mid-session switches (`agent-preset/locked`),
|
|
2644
|
+
// so PINNED SESSIONS cannot be migrated by any official API. The DEPLOYMENT
|
|
2645
|
+
// DEFAULT, however, is one writable setting: `selectedDefault` on the
|
|
2646
|
+
// `agent-preset-registry` row (volatile; the official preset picker writes
|
|
2647
|
+
// it through `settings.update('agent-preset-registry', ...)`). While
|
|
2648
|
+
// variantPresets is OFF (the user did NOT keep the old modes) and that
|
|
2649
|
+
// default still names one of OUR variants, migrate it to the official
|
|
2650
|
+
// successor once — idempotent (a migrated or user-chosen official default
|
|
2651
|
+
// never matches PRESET_IDS again), roster-checked (the official id renamed
|
|
2652
|
+
// once already: code→ptc — a missing target stands down instead of
|
|
2653
|
+
// guessing), written through the OFFICIAL settings seam, and verified by
|
|
2654
|
+
// read-back (a write that did not stick is reported, never claimed).
|
|
2655
|
+
// With variantPresets ON nothing here runs: the variants stay registered,
|
|
2656
|
+
// so a variant default keeps working as-is.
|
|
2657
|
+
try {
|
|
2658
|
+
if (ctx.agentPresets && typeof ctx.agentPresets.register === 'function') {
|
|
2659
|
+
ctx.inject(['settings'], (settingsCtx) => {
|
|
2660
|
+
void (async () => {
|
|
2661
|
+
try {
|
|
2662
|
+
const settings = settingsCtx.settings
|
|
2663
|
+
if (!settings || typeof settings.update !== 'function') return
|
|
2664
|
+
// The switch is the whole contract: keep-old-modes ON means a
|
|
2665
|
+
// variant default is a legitimate choice and stays untouched.
|
|
2666
|
+
if (liveSettings.variantPresets() === true) return
|
|
2667
|
+
const readDefault = () => { try { return ctx.agentPresets.defaultId } catch { return undefined } }
|
|
2668
|
+
const current = readDefault()
|
|
2669
|
+
if (typeof current !== 'string' || !PRESET_IDS.includes(current)) return
|
|
2670
|
+
const target = VARIANT_DEFAULT_SUCCESSORS[current]
|
|
2671
|
+
if (typeof target !== 'string') return
|
|
2672
|
+
// The successor must exist in the CURRENT roster: official ids
|
|
2673
|
+
// renamed once already (code→ptc), and writing an unknown id
|
|
2674
|
+
// would trade a known failure for a worse one.
|
|
2675
|
+
const roster = await ctx.agentPresets.list()
|
|
2676
|
+
if (!Array.isArray(roster) || !roster.some((row) => row && row.id === target)) {
|
|
2677
|
+
console.warn(TAG + ' default-preset migration stood down: the deployment default is the variant "'
|
|
2678
|
+
+ current + '" but the successor "' + target + '" is not registered on this host.'
|
|
2679
|
+
+ ' Set the default manually among the OFFICIAL presets, or turn variantPresets on.')
|
|
2680
|
+
return
|
|
2681
|
+
}
|
|
2682
|
+
try {
|
|
2683
|
+
await settings.update('agent-preset-registry', { selectedDefault: target })
|
|
2684
|
+
} catch (error) {
|
|
2685
|
+
console.warn(TAG + ' default-preset migration write failed (' + (error?.message ?? error)
|
|
2686
|
+
+ '): the deployment default is still the variant "' + current
|
|
2687
|
+
+ '" — NEW sessions would fail with agent-preset/not-found.'
|
|
2688
|
+
+ ' Fix: set an OFFICIAL default in the preset picker, or turn variantPresets on.')
|
|
2689
|
+
return
|
|
2690
|
+
}
|
|
2691
|
+
const after = readDefault()
|
|
2692
|
+
if (after === target) {
|
|
2693
|
+
console.log(TAG + ' deployment default migrated: "' + current + '" -> "' + target
|
|
2694
|
+
+ '" (variantPresets is off). Old sessions pinned to a variant still need a NEW'
|
|
2695
|
+
+ ' session — the official agent-preset/locked rule blocks a mid-session switch.')
|
|
2696
|
+
} else {
|
|
2697
|
+
console.warn(TAG + ' default-preset migration did not stick (read back "'
|
|
2698
|
+
+ (after === undefined ? 'unreadable' : after) + '"). Set the default manually in'
|
|
2699
|
+
+ ' Settings -> agent preset, or turn variantPresets on.')
|
|
2700
|
+
}
|
|
2701
|
+
} catch (error) {
|
|
2702
|
+
console.log(TAG + ' default-preset migration failed: ' + (error?.message ?? error))
|
|
2703
|
+
}
|
|
2704
|
+
})()
|
|
2705
|
+
})
|
|
2706
|
+
}
|
|
2707
|
+
} catch (error) {
|
|
2708
|
+
console.log(TAG + ' default-preset migration wiring failed: ' + (error?.message ?? error))
|
|
2709
|
+
}
|
|
2710
|
+
|
|
2711
|
+
// ── FastCtx bridge (v0.35.0): the gb_* file tools, default ON ────────────
|
|
2712
|
+
// Additions, never replacements: the official read/grep/glob/edit tools and
|
|
2713
|
+
// their file sandbox stay first choice in every description. The bridge
|
|
2714
|
+
// mounts nothing outside win32, nothing when the payload is absent, and
|
|
2715
|
+
// stands down entirely the moment dsh-ops (ops_* tools) is detected.
|
|
2716
|
+
if (process.platform === 'win32') {
|
|
2717
|
+
try {
|
|
2718
|
+
const { createRequire } = await import('node:module')
|
|
2719
|
+
mountFastctx(ctx, {
|
|
2720
|
+
platform: process.platform,
|
|
2721
|
+
enabled: () => liveSettings.fastctxTools(),
|
|
2722
|
+
createRequireFrom: (base) => createRequire(base ?? import.meta.url),
|
|
2723
|
+
tools: (c) => { try { return c.get('tools') } catch { return undefined } },
|
|
2724
|
+
msysToWin: (p) => translateMsysPath(p, buildTranslateEnv(readConfiguredBashPath())),
|
|
2725
|
+
echo: (text) => (liveSettings.dialect().posixPaths === true ? windowsToMsys(text) : text),
|
|
2726
|
+
log: (m) => console.log(TAG + ' ' + m),
|
|
2727
|
+
})
|
|
2728
|
+
} catch (error) {
|
|
2729
|
+
console.log(TAG + ' FastCtx bridge wiring failed: ' + (error?.message ?? error))
|
|
2730
|
+
}
|
|
2731
|
+
}
|
|
2732
|
+
|
|
2512
2733
|
// ── era split: declarative registration on dsh >= 0.1.7 ──────────────────
|
|
2513
2734
|
// The register method IS the era signal. On the new host the whole
|
|
2514
2735
|
// materialization path below is dead code (nothing reads the directory any
|
|
2515
2736
|
// more), so this branch serves the variants and returns.
|
|
2516
2737
|
if (ctx.agentPresets && typeof ctx.agentPresets.register === 'function') {
|
|
2517
2738
|
try {
|
|
2518
|
-
await runDeclarativeEra(ctx, presetIds, () => liveSettings.suppressPeerCordis(), readBashResolution)
|
|
2739
|
+
await runDeclarativeEra(ctx, presetIds, () => liveSettings.suppressPeerCordis(), readBashResolution, () => liveSettings.variantPresets())
|
|
2519
2740
|
} catch (error) {
|
|
2520
2741
|
console.log(TAG + ' declarative registration failed: ' + (error && error.message ? error.message : error))
|
|
2521
2742
|
}
|
|
@@ -2524,4 +2745,4 @@ export async function apply(ctx, config = {}) {
|
|
|
2524
2745
|
|
|
2525
2746
|
}
|
|
2526
2747
|
// Test surface: pure helpers, no Cordis context required.
|
|
2527
|
-
export const _internal = { PRESET_IDS, PEER_COVERED_PRESET_ID, PEER_CAPABILITY, isDelegatedAgent, dialectApplies, PEER_PYTHON_FIELD, PEER_PYTHON_BACKEND_FIELD, peerFact, peerBackend, pythonBackendActive, effectivePresetIds, translateDispatch, translateMsysPath, translatePathArguments, rewriteCodePaths, scanCodeLiterals, programPrelude, translateGlobArguments, buildTranslateEnv, rewriteErrorContent, rewriteErrorMessage, rewriteFailureMessage, msysEcho, driveToMsys, pathEcho, ERROR_CONTENT_TOOLS, windowsToMsys, rewriteResultPaths, adoptSidebarShell, MARKER_FILE, classify, hashTree, installRegisterShim, probeHostExtras }
|
|
2748
|
+
export const _internal = { PRESET_IDS, VARIANT_DEFAULT_SUCCESSORS, PEER_COVERED_PRESET_ID, PEER_CAPABILITY, isDelegatedAgent, dialectApplies, PEER_PYTHON_FIELD, PEER_PYTHON_BACKEND_FIELD, peerFact, peerBackend, pythonBackendActive, effectivePresetIds, translateDispatch, translateMsysPath, translatePathArguments, rewriteCodePaths, scanCodeLiterals, programPrelude, translateGlobArguments, buildTranslateEnv, rewriteErrorContent, rewriteErrorMessage, rewriteFailureMessage, msysEcho, driveToMsys, pathEcho, ERROR_CONTENT_TOOLS, windowsToMsys, rewriteResultPaths, adoptSidebarShell, MARKER_FILE, classify, hashTree, installRegisterShim, probeHostExtras }
|