martty 0.3.1 → 0.3.2-beta.0
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 +5 -4
- package/lib/acp-agent-pool.js +98 -3
- package/lib/harness-registry.js +2 -2
- package/lib/harnesses.js +11 -2
- package/lib/tui-plugin-store.js +34 -3
- package/package.json +9 -9
- package/skills/tui-plugin-development/SKILL.md +1 -1
package/README.md
CHANGED
|
@@ -198,10 +198,11 @@ Creator-authored UI Presets and Theme Plugins preview as process-local dynamic
|
|
|
198
198
|
Packages, then persist explicitly under `$MARTTY_HOME/plugins` through
|
|
199
199
|
`tui_plugin_save`; `tui_plugin_read` resumes authoring after restart.
|
|
200
200
|
|
|
201
|
-
`MARTTY_HOME` resolves explicitly first, then to
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
201
|
+
`MARTTY_HOME` (or `OMA_HOME`) resolves explicitly first, then to
|
|
202
|
+
`$DSH_HOME/.oma`, then to `~/.oma` — the configuration home Martty shares
|
|
203
|
+
with Backchat. UI choices live in `$MARTTY_HOME/settings.json`. On first use,
|
|
204
|
+
a legacy `.martty` directory and old Creator artifacts/settings are copied
|
|
205
|
+
forward without deleting or overwriting the old files.
|
|
205
206
|
|
|
206
207
|
Third-party TUI plugins remain ordinary installed packages. Their Host-side
|
|
207
208
|
registrar contributes an absolute Client module entry to `tuiClientPlugins`;
|
package/lib/acp-agent-pool.js
CHANGED
|
@@ -10,6 +10,21 @@ const identity = spec => JSON.stringify([spec.command, spec.args ?? [],
|
|
|
10
10
|
const namespace = spec => createHash('sha256').update(identity(spec)).digest('hex').slice(0, 24)
|
|
11
11
|
const setupMethods = new Set(['session/new', 'session/load', 'session/resume'])
|
|
12
12
|
|
|
13
|
+
/** `configOptions` array from a setup/set result or a `config_option_update`. */
|
|
14
|
+
function readConfigOptions(value) {
|
|
15
|
+
const found = value?.configOptions ?? value?.config_options
|
|
16
|
+
return Array.isArray(found) ? found : undefined
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** `[configId, value]` pair for one option entry, or undefined when incomplete. */
|
|
20
|
+
function optionEntry(option) {
|
|
21
|
+
if (option === null || typeof option !== 'object' || Array.isArray(option)) return undefined
|
|
22
|
+
const id = option.id ?? option.configId ?? option.config_id
|
|
23
|
+
const value = option.currentValue ?? option.current_value
|
|
24
|
+
if (typeof id !== 'string' || id.length === 0 || value === undefined) return undefined
|
|
25
|
+
return [id, structuredClone(value)]
|
|
26
|
+
}
|
|
27
|
+
|
|
13
28
|
export function createAgentPool(initial, { spawnAgent, resolveAgent, diagnosticError, timeoutMs = 20 * 60_000 }) {
|
|
14
29
|
const input = new PassThrough()
|
|
15
30
|
const output = new PassThrough()
|
|
@@ -30,10 +45,15 @@ export function createAgentPool(initial, { spawnAgent, resolveAgent, diagnosticE
|
|
|
30
45
|
const writeAgent = (owner, value) => owner.handle.stdin.write(JSON.stringify(value) + '\n')
|
|
31
46
|
|
|
32
47
|
function metadata(owner) {
|
|
48
|
+
// Send Now reads this snapshot per session (`steer_route`). Steering and
|
|
49
|
+
// MiniMax extensions are advertised on initialize `_meta`, which
|
|
50
|
+
// `agentCapabilities` does not carry.
|
|
51
|
+
const negotiated = owner.init?._meta
|
|
33
52
|
return {
|
|
34
53
|
id: owner.id,
|
|
35
54
|
agentInfo: owner.init?.agentInfo,
|
|
36
55
|
agentCapabilities: owner.init?.agentCapabilities ?? {},
|
|
56
|
+
...(negotiated && typeof negotiated === 'object' ? { _meta: negotiated } : {}),
|
|
37
57
|
authMethods: (owner.init?.authMethods ?? []).map(method => {
|
|
38
58
|
const id = owner.id === 'h1' ? method.id : `${owner.id}:${method.id}`
|
|
39
59
|
authMethods.set(id, { owner, id: method.id })
|
|
@@ -80,9 +100,17 @@ export function createAgentPool(initial, { spawnAgent, resolveAgent, diagnosticE
|
|
|
80
100
|
}
|
|
81
101
|
if (setupMethods.has(pending.method) && result && typeof result === 'object') {
|
|
82
102
|
const raw = result.sessionId ?? pending.params?.sessionId
|
|
83
|
-
|
|
103
|
+
const bound = sessionId(owner, raw)
|
|
104
|
+
recordOptions(owner, bound, readConfigOptions(result))
|
|
105
|
+
result = { ...result, sessionId: bound,
|
|
84
106
|
_meta: { ...result._meta, marttyConnection: { ...metadata(owner), cwd: pending.params?.cwd } } }
|
|
85
107
|
}
|
|
108
|
+
if (pending.method === 'session/set_config_option' && result && typeof result === 'object') {
|
|
109
|
+
recordOptions(owner, pending.sessionKey, readConfigOptions(result)
|
|
110
|
+
?? (pending.params?.configId !== undefined
|
|
111
|
+
? [{ id: pending.params.configId, currentValue: pending.params.value }]
|
|
112
|
+
: undefined))
|
|
113
|
+
}
|
|
86
114
|
if (pending.method === 'session/list' && Array.isArray(result?.sessions)) {
|
|
87
115
|
result = { ...result, sessions: result.sessions.map(session => ({ ...session,
|
|
88
116
|
sessionId: sessionId(owner, session.sessionId) })) }
|
|
@@ -100,12 +128,60 @@ export function createAgentPool(initial, { spawnAgent, resolveAgent, diagnosticE
|
|
|
100
128
|
owner.pending.clear()
|
|
101
129
|
}
|
|
102
130
|
|
|
131
|
+
/**
|
|
132
|
+
* Track each session's config options and what the connection last applied.
|
|
133
|
+
* `session/set_config_option` is session-scoped in ACP, but agents like
|
|
134
|
+
* pi-acp apply it to global state — a newer session's defaults then leak
|
|
135
|
+
* into older sessions' turns. Remembering every session's own options lets
|
|
136
|
+
* `session/prompt` re-assert them first, so each turn runs the model and
|
|
137
|
+
* effort its session chose. New sessions never assert: they just record
|
|
138
|
+
* the defaults their setup snapshot reported.
|
|
139
|
+
* @param {*} owner
|
|
140
|
+
* @param {string} sessionKey - namespaced session id
|
|
141
|
+
* @param {Array|undefined} options - `configOptions` entries
|
|
142
|
+
*/
|
|
143
|
+
function recordOptions(owner, sessionKey, options) {
|
|
144
|
+
if (typeof sessionKey !== 'string' || !options) return
|
|
145
|
+
const entries = options.map(optionEntry).filter(Boolean)
|
|
146
|
+
if (entries.length === 0) return
|
|
147
|
+
const config = owner.configs.get(sessionKey) ?? new Map()
|
|
148
|
+
for (const [id, value] of entries) {
|
|
149
|
+
config.set(id, value)
|
|
150
|
+
owner.applied.set(id, value)
|
|
151
|
+
}
|
|
152
|
+
owner.configs.set(sessionKey, config)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Re-apply a session's recorded config options the connection no longer
|
|
157
|
+
* holds — one `set_config_option` per drifted option, in recorded order.
|
|
158
|
+
* Best effort: a rejected assert must not block the turn it guarded.
|
|
159
|
+
*/
|
|
160
|
+
async function applySessionConfig(owner, sessionKey) {
|
|
161
|
+
const config = owner.configs.get(sessionKey)
|
|
162
|
+
const bound = sessions.get(sessionKey)
|
|
163
|
+
if (!config || !bound || bound.owner !== owner || owner.failed || closed) return
|
|
164
|
+
for (const [configId, value] of config) {
|
|
165
|
+
if (JSON.stringify(owner.applied.get(configId)) === JSON.stringify(value)) continue
|
|
166
|
+
const id = `martty-config-${++nextRequest}`
|
|
167
|
+
const params = { sessionId: bound.raw, configId, value }
|
|
168
|
+
const result = await new Promise((resolve, reject) => {
|
|
169
|
+
owner.pending.set(id, { resolve, reject, method: 'session/set_config_option', params, sessionKey })
|
|
170
|
+
writeAgent(owner, { jsonrpc: '2.0', id, method: 'session/set_config_option', params })
|
|
171
|
+
}).catch(() => undefined)
|
|
172
|
+
if (result === undefined) break // assert failed — keep remaining options eligible
|
|
173
|
+
recordOptions(owner, sessionKey, readConfigOptions(result)
|
|
174
|
+
?? [{ id: configId, currentValue: value }])
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
103
178
|
function connection(spec) {
|
|
104
179
|
const key = identity(spec)
|
|
105
180
|
const existing = connections.get(key)
|
|
106
181
|
if (existing && !existing.failed) return existing
|
|
107
182
|
const owner = { id: `h${++nextConnection}`, namespace: namespace(spec), spec, handle: spawnAgent(spec),
|
|
108
|
-
sessions: new Map(), pending: new Map(), init: undefined, initializing: undefined, failed: undefined
|
|
183
|
+
sessions: new Map(), pending: new Map(), init: undefined, initializing: undefined, failed: undefined,
|
|
184
|
+
configs: new Map(), applied: new Map(), configChain: Promise.resolve() }
|
|
109
185
|
connections.set(key, owner)
|
|
110
186
|
owner.handle.child.on('error', error => fail(owner, error))
|
|
111
187
|
owner.handle.child.once('close', (code, signal) => fail(owner,
|
|
@@ -124,6 +200,10 @@ export function createAgentPool(initial, { spawnAgent, resolveAgent, diagnosticE
|
|
|
124
200
|
return
|
|
125
201
|
}
|
|
126
202
|
const forwarded = { ...message, params: incomingParams(owner, message.params) }
|
|
203
|
+
if (message.method === 'session/update'
|
|
204
|
+
&& forwarded.params?.update?.sessionUpdate === 'config_option_update') {
|
|
205
|
+
recordOptions(owner, forwarded.params.sessionId, readConfigOptions(forwarded.params.update))
|
|
206
|
+
}
|
|
127
207
|
if (message.id !== undefined) {
|
|
128
208
|
const id = `martty-agent-${++nextRequest}`
|
|
129
209
|
callbacks.set(id, { owner, id: message.id })
|
|
@@ -214,6 +294,8 @@ export function createAgentPool(initial, { spawnAgent, resolveAgent, diagnosticE
|
|
|
214
294
|
if (message.method.startsWith('_dsh/cordis/') && readCordisCapability(owner.init) === null) {
|
|
215
295
|
throw new Error('agent has not advertised _dsh/cordis')
|
|
216
296
|
}
|
|
297
|
+
const sessionKey = typeof params?.sessionId === 'string' ? params.sessionId
|
|
298
|
+
: typeof params?.session_id === 'string' ? params.session_id : undefined
|
|
217
299
|
if (params && typeof params === 'object') {
|
|
218
300
|
params = { ...params }
|
|
219
301
|
for (const key of ['sessionId', 'session_id']) {
|
|
@@ -224,9 +306,22 @@ export function createAgentPool(initial, { spawnAgent, resolveAgent, diagnosticE
|
|
|
224
306
|
const forwarded = { ...message, params }
|
|
225
307
|
if (message.id !== undefined) {
|
|
226
308
|
const id = `martty-client-${++nextRequest}`
|
|
227
|
-
owner.pending.set(id, { id: message.id, method: message.method, params })
|
|
309
|
+
owner.pending.set(id, { id: message.id, method: message.method, params, sessionKey })
|
|
228
310
|
forwarded.id = id
|
|
229
311
|
}
|
|
312
|
+
if (message.method === 'session/prompt' && sessionKey !== undefined) {
|
|
313
|
+
// The prompt lands on stdin only after its session's config options
|
|
314
|
+
// are re-asserted — the chain keeps cross-session order. Registering
|
|
315
|
+
// the pending reply above (never inside the chain) keeps close() able
|
|
316
|
+
// to settle it while an assert is still in flight.
|
|
317
|
+
owner.configChain = owner.configChain.then(async () => {
|
|
318
|
+
// Asserts resolve `undefined` on a failed set_config_option rather
|
|
319
|
+
// than rejecting, so this chain cannot drop the prompt.
|
|
320
|
+
await applySessionConfig(owner, sessionKey)
|
|
321
|
+
if (!closed && !owner.failed) writeAgent(owner, forwarded)
|
|
322
|
+
})
|
|
323
|
+
return
|
|
324
|
+
}
|
|
230
325
|
writeAgent(owner, forwarded)
|
|
231
326
|
} catch (error) {
|
|
232
327
|
if (message.id !== undefined) {
|
package/lib/harness-registry.js
CHANGED
|
@@ -19,13 +19,13 @@ import { downloadFile } from './download.js'
|
|
|
19
19
|
|
|
20
20
|
export const ACP_REGISTRY_URL = 'https://cdn.agentclientprotocol.com/registry/v1/latest/registry.json'
|
|
21
21
|
|
|
22
|
-
const OPENMA_PI_ACP = '@openma/pi-acp@
|
|
22
|
+
export const OPENMA_PI_ACP = '@openma/pi-acp@latest'
|
|
23
23
|
|
|
24
24
|
function preferMarttyPiAcp(records) {
|
|
25
25
|
return records.map((record) => record.id === 'pi-acp' ? {
|
|
26
26
|
...record,
|
|
27
27
|
label: 'Pi (OpenMA)',
|
|
28
|
-
version: '
|
|
28
|
+
version: 'latest',
|
|
29
29
|
distributions: [{
|
|
30
30
|
type: 'npx', command: 'npx', args: [OPENMA_PI_ACP], env: {},
|
|
31
31
|
}],
|
package/lib/harnesses.js
CHANGED
|
@@ -16,12 +16,15 @@ import {
|
|
|
16
16
|
installRegistryBinary,
|
|
17
17
|
managedBinaryPath,
|
|
18
18
|
normalizeAcpRegistry,
|
|
19
|
+
OPENMA_PI_ACP,
|
|
19
20
|
readAcpRegistrySnapshot,
|
|
20
21
|
} from './harness-registry.js'
|
|
21
22
|
|
|
22
23
|
export { fetchAcpRegistry } from './harness-registry.js'
|
|
23
24
|
|
|
24
25
|
const HARNESS_ID = /^[a-z0-9][a-z0-9-]*$/
|
|
26
|
+
const PI_ACP_LATEST = OPENMA_PI_ACP
|
|
27
|
+
const PI_ACP_SPEC = /^(?:@openma\/)?pi-acp(?:@.+)?$/
|
|
25
28
|
const ANSI = Object.freeze({ reset: '\x1b[0m', bold: '\x1b[1m', dim: '\x1b[2m', cyan: '\x1b[36m', green: '\x1b[32m' })
|
|
26
29
|
|
|
27
30
|
// Kept as a source-compatible empty export. The source of truth is the
|
|
@@ -361,8 +364,14 @@ function validateHarness(value) {
|
|
|
361
364
|
|| Object.entries(env).some(([key, item]) => key.length === 0 || typeof item !== 'string'))) {
|
|
362
365
|
throw new Error('harness env must be an object of strings')
|
|
363
366
|
}
|
|
364
|
-
const
|
|
365
|
-
|
|
367
|
+
const isNpx = /^npx(?:\.(?:cmd|bat|exe))?$/i.test(path.win32.basename(value.command))
|
|
368
|
+
const normalizedArgs = isNpx
|
|
369
|
+
? [...args]
|
|
370
|
+
.filter((arg) => arg !== '--yes' && arg !== '--prefer-offline')
|
|
371
|
+
// A pinned pi-acp spec (any old `pi-acp@x` or `@openma/pi-acp@x` entry)
|
|
372
|
+
// always resolves `latest` at runtime instead — harness upgrades ship
|
|
373
|
+
// through npm, never through a Martty release.
|
|
374
|
+
.map((arg) => PI_ACP_SPEC.test(arg) ? PI_ACP_LATEST : arg)
|
|
366
375
|
: [...args]
|
|
367
376
|
return {
|
|
368
377
|
id: value.id,
|
package/lib/tui-plugin-store.js
CHANGED
|
@@ -76,14 +76,45 @@ export function tuiPluginRoot(env = process.env) {
|
|
|
76
76
|
return path.join(marttyHome(env), 'plugins')
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
+
/**
|
|
80
|
+
* Martty's configuration home, shared with Backchat: `~/.oma`.
|
|
81
|
+
* Resolution order: explicit `MARTTY_HOME`/`OMA_HOME`, then `$DSH_HOME/.oma`,
|
|
82
|
+
* then `~/.oma`. When the new home is missing but a legacy `.martty`
|
|
83
|
+
* directory sits next to it, its contents are migrated once (config, cache,
|
|
84
|
+
* sessions, managed binaries) so existing installs keep their state.
|
|
85
|
+
*/
|
|
79
86
|
export function marttyHome(env = process.env, userHome = homedir()) {
|
|
80
87
|
if (typeof env.MARTTY_HOME === 'string' && env.MARTTY_HOME.length > 0) {
|
|
81
88
|
return env.MARTTY_HOME
|
|
82
89
|
}
|
|
83
|
-
if (typeof env.
|
|
84
|
-
return
|
|
90
|
+
if (typeof env.OMA_HOME === 'string' && env.OMA_HOME.length > 0) {
|
|
91
|
+
return env.OMA_HOME
|
|
85
92
|
}
|
|
86
|
-
|
|
93
|
+
const base = typeof env.DSH_HOME === 'string' && env.DSH_HOME.length > 0
|
|
94
|
+
? env.DSH_HOME
|
|
95
|
+
: userHome
|
|
96
|
+
return migrateMarttyHome(base)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function migrateMarttyHome(base) {
|
|
100
|
+
const home = path.join(base, '.oma')
|
|
101
|
+
const legacy = path.join(base, '.martty')
|
|
102
|
+
if (existsSync(home) || !existsSync(legacy)) return home
|
|
103
|
+
// Stage the copy under a temporary sibling so a crash cannot leave a
|
|
104
|
+
// half-migrated `.oma` behind; the legacy directory is left untouched.
|
|
105
|
+
const staged = `${home}.migrating-${process.pid}`
|
|
106
|
+
try {
|
|
107
|
+
rmSync(staged, { recursive: true, force: true })
|
|
108
|
+
cpSync(legacy, staged, { recursive: true, errorOnExist: true })
|
|
109
|
+
renameSync(staged, home)
|
|
110
|
+
process.stderr.write(`martty: migrated ${legacy} to ${home} (shared with Backchat)\n`)
|
|
111
|
+
} catch {
|
|
112
|
+
rmSync(staged, { recursive: true, force: true })
|
|
113
|
+
// Migration is best effort: an unmigrated legacy directory keeps working
|
|
114
|
+
// under its old name rather than blocking startup.
|
|
115
|
+
return legacy
|
|
116
|
+
}
|
|
117
|
+
return home
|
|
87
118
|
}
|
|
88
119
|
|
|
89
120
|
export function legacyTuiPluginRoot(env = process.env, userHome = homedir()) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "martty",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2-beta.0",
|
|
4
4
|
"description": "Terminal-native ACP client UI; Cordis client tree, any ACP agent",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"scripts": {
|
|
17
17
|
"test:harness-ui": "node --test ../scripts/harness-management-tui.test.mjs ../scripts/harness-session-tui.test.mjs",
|
|
18
18
|
"pretest": "node --test ../scripts/workflow-release.test.mjs ../scripts/package-alias.test.mjs ../scripts/harness-removal.test.mjs",
|
|
19
|
-
"test": "node --test ../scripts/download.test.mjs ../scripts/package-native.test.mjs ../scripts/check-release-tag.test.mjs ../scripts/check-static-elf.test.mjs ../scripts/smoke-old-linux.test.mjs ../scripts/cargo-guard.test.mjs ../scripts/build-npm.test.mjs ../scripts/client-profile.test.mjs ../scripts/plugin-runner.test.mjs ../scripts/profile-link-resolution.test.mjs ../scripts/packaged-acp-permission.test.mjs ../scripts/profile-smoke-tui.test.mjs ../scripts/release.test.mjs ../scripts/jsonrpc-line-transport.test.mjs ../scripts/tui-theme.test.mjs ../scripts/tui-presets.test.mjs ../scripts/tui-plugin-store.test.mjs ../scripts/tui-local-plugins.test.mjs ../scripts/tui-client-plugin-registry.test.mjs ../scripts/tui-slots.test.mjs ../scripts/tui-commands.test.mjs ../scripts/tui-overlay.test.mjs ../scripts/tui-agents.test.mjs ../scripts/tui-queue.test.mjs ../scripts/mux.test.mjs ../scripts/acp-client.test.mjs ../scripts/acp-agent-pool.test.mjs ../scripts/harnesses.test.mjs ../scripts/harness-discovery.test.mjs ../scripts/harness-discovery-scenario.test.mjs ../scripts/harness-view.test.mjs ../scripts/harness-onboarding.test.mjs ../scripts/harness-registry.test.mjs ../scripts/harness-badge.test.mjs ../scripts/harness-package.test.mjs ../scripts/acp-client-events.test.mjs ../scripts/acp-session-config.test.mjs ../scripts/acp-session-plan.test.mjs ../scripts/acp-session-stats.test.mjs ../scripts/acp-session-status.test.mjs ../scripts/agents-view.test.mjs ../scripts/plan-view.test.mjs ../scripts/queue-view.test.mjs ../scripts/stats-view.test.mjs ../scripts/status-view.test.mjs ../scripts/deepseek-logo.test.mjs ../scripts/runner.test.mjs ../scripts/inspect.test.mjs ../scripts/creator-overlay.test.mjs ../scripts/real-agent-e2e.test.mjs",
|
|
19
|
+
"test": "node --test ../scripts/download.test.mjs ../scripts/package-native.test.mjs ../scripts/check-release-tag.test.mjs ../scripts/release-check.test.mjs ../scripts/check-static-elf.test.mjs ../scripts/smoke-old-linux.test.mjs ../scripts/cargo-guard.test.mjs ../scripts/build-npm.test.mjs ../scripts/client-profile.test.mjs ../scripts/plugin-runner.test.mjs ../scripts/profile-link-resolution.test.mjs ../scripts/packaged-acp-permission.test.mjs ../scripts/profile-smoke-tui.test.mjs ../scripts/release.test.mjs ../scripts/jsonrpc-line-transport.test.mjs ../scripts/tui-theme.test.mjs ../scripts/tui-presets.test.mjs ../scripts/tui-plugin-store.test.mjs ../scripts/tui-local-plugins.test.mjs ../scripts/tui-client-plugin-registry.test.mjs ../scripts/tui-slots.test.mjs ../scripts/tui-commands.test.mjs ../scripts/tui-overlay.test.mjs ../scripts/tui-agents.test.mjs ../scripts/tui-queue.test.mjs ../scripts/mux.test.mjs ../scripts/acp-client.test.mjs ../scripts/acp-agent-pool.test.mjs ../scripts/harnesses.test.mjs ../scripts/harness-discovery.test.mjs ../scripts/harness-discovery-scenario.test.mjs ../scripts/harness-view.test.mjs ../scripts/harness-onboarding.test.mjs ../scripts/harness-registry.test.mjs ../scripts/harness-badge.test.mjs ../scripts/harness-package.test.mjs ../scripts/acp-client-events.test.mjs ../scripts/acp-session-config.test.mjs ../scripts/acp-session-plan.test.mjs ../scripts/acp-session-stats.test.mjs ../scripts/acp-session-status.test.mjs ../scripts/agents-view.test.mjs ../scripts/plan-view.test.mjs ../scripts/queue-view.test.mjs ../scripts/stats-view.test.mjs ../scripts/status-view.test.mjs ../scripts/deepseek-logo.test.mjs ../scripts/runner.test.mjs ../scripts/inspect.test.mjs ../scripts/creator-overlay.test.mjs ../scripts/real-agent-e2e.test.mjs",
|
|
20
20
|
"test:profile-install-matrix": "node --test ../scripts/profile-install-matrix.test.mjs"
|
|
21
21
|
},
|
|
22
22
|
"publishConfig": {
|
|
@@ -76,13 +76,13 @@
|
|
|
76
76
|
"dependencies": {
|
|
77
77
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
78
78
|
"@lobehub/icons-static-svg": "1.95.0",
|
|
79
|
-
"@openma/deepseek-harness-acp": "0.4.
|
|
79
|
+
"@openma/deepseek-harness-acp": "0.4.37",
|
|
80
80
|
"@resvg/resvg-js": "2.6.2",
|
|
81
81
|
"cross-spawn": "^7.0.6",
|
|
82
82
|
"node-downloader-helper": "2.1.11"
|
|
83
83
|
},
|
|
84
84
|
"devDependencies": {
|
|
85
|
-
"@deepseek-ai/dsh": "0.
|
|
85
|
+
"@deepseek-ai/dsh": "0.2.0-rc.2"
|
|
86
86
|
},
|
|
87
87
|
"engines": {
|
|
88
88
|
"node": ">=22.19.0"
|
|
@@ -96,10 +96,10 @@
|
|
|
96
96
|
"agent-client-protocol"
|
|
97
97
|
],
|
|
98
98
|
"optionalDependencies": {
|
|
99
|
-
"@openma/martty-darwin-arm64": "0.3.
|
|
100
|
-
"@openma/martty-darwin-x64": "0.3.
|
|
101
|
-
"@openma/martty-linux-x64": "0.3.
|
|
102
|
-
"@openma/martty-linux-arm64": "0.3.
|
|
103
|
-
"@openma/martty-win32-x64": "0.3.
|
|
99
|
+
"@openma/martty-darwin-arm64": "0.3.2-beta.0",
|
|
100
|
+
"@openma/martty-darwin-x64": "0.3.2-beta.0",
|
|
101
|
+
"@openma/martty-linux-x64": "0.3.2-beta.0",
|
|
102
|
+
"@openma/martty-linux-arm64": "0.3.2-beta.0",
|
|
103
|
+
"@openma/martty-win32-x64": "0.3.2-beta.0"
|
|
104
104
|
}
|
|
105
105
|
}
|
|
@@ -56,7 +56,7 @@ depend on a value returned by `apply()` as the disposer; register effects
|
|
|
56
56
|
through the inspected Cordis APIs.
|
|
57
57
|
|
|
58
58
|
The authoring root is `$MARTTY_HOME/plugins`; `MARTTY_HOME` resolves from the
|
|
59
|
-
explicit environment variable
|
|
59
|
+
explicit environment variable or `OMA_HOME`, then `$DSH_HOME/.oma`, then `~/.oma`.
|
|
60
60
|
User selections live separately in `$MARTTY_HOME/settings.json`.
|
|
61
61
|
|
|
62
62
|
## Inspect is the authority
|