mixdog 1.2.6 → 1.3.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/LICENSES/simple-icons-CC0-1.0.txt +30 -0
- package/NOTICE.md +19 -0
- package/package.json +4 -1
- package/scripts/check-model-recommendations.mjs +89 -0
- package/scripts/gate-local.mjs +7 -0
- package/scripts/lib/isolated-test-env.mjs +16 -0
- package/src/agents/reviewer/AGENT.md +4 -2
- package/src/agents/reviewer/agent.json +1 -1
- package/src/defaults/shipped-history.json +7 -0
- package/src/defaults/skills/browser-use/SKILL.md +5 -0
- package/src/defaults/skills/memory-management/SKILL.md +4 -1
- package/src/defaults/skills/setup/references/actions.md +11 -4
- package/src/defaults/skills/setup-guide/SKILL.md +175 -0
- package/src/defaults/skills/setup-guide/model-recommendations.json +333 -0
- package/src/lib/rules-builder.cjs +55 -6
- package/src/rules/agent/AGENT.md +4 -0
- package/src/rules/agent-mode/AGENT_MODE.md +24 -0
- package/src/rules/agent-mode/MIXY.md +21 -0
- package/src/rules/agent-mode/ROUTINE.md +6 -0
- package/src/rules/lead/LEAD.md +7 -3
- package/src/rules/shared/70-delivery.md +3 -0
- package/src/runtime/agent/orchestrator/agent-runtime/room-supervisor-completion.mjs +86 -0
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +77 -14
- package/src/runtime/agent/orchestrator/context/role-instructions.mjs +182 -13
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +4 -2
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +215 -0
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +5 -4
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +10 -1
- package/src/runtime/agent/orchestrator/mcp/client.mjs +115 -11
- package/src/runtime/agent/orchestrator/mcp/oauth-account.mjs +97 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +49 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +59 -9
- package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +32 -7
- package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +45 -6
- package/src/runtime/agent/orchestrator/mcp/oauth.mjs +195 -6
- package/src/runtime/agent/orchestrator/mcp/server-connectors.mjs +17 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +10 -3
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +4 -0
- package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/openai-error-contract.mjs +17 -12
- package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +10 -0
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +96 -1
- package/src/runtime/agent/orchestrator/runtime-core/context-status-shape.mjs +4 -0
- package/src/runtime/agent/orchestrator/runtime-core/extension-scopes.mjs +6 -4
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +12 -0
- package/src/runtime/agent/orchestrator/runtime-core/plugin-mcp.mjs +1 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +12 -6
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +32 -5
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +10 -4
- package/src/runtime/agent/orchestrator/runtime-core/workflow/agents.mjs +4 -1
- package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +50 -20
- package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/agent-home.d.mts +4 -0
- package/src/runtime/agent/orchestrator/session/agent-home.mjs +33 -0
- package/src/runtime/agent/orchestrator/session/agent-mode.mjs +62 -0
- package/src/runtime/agent/orchestrator/session/agent-room-supervisor.d.mts +31 -0
- package/src/runtime/agent/orchestrator/session/agent-room-supervisor.mjs +241 -0
- package/src/runtime/agent/orchestrator/session/agent-room.d.mts +162 -0
- package/src/runtime/agent/orchestrator/session/agent-room.mjs +641 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +7 -1
- package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +6 -2
- package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +165 -0
- package/src/runtime/agent/orchestrator/session/human-gate/held-message.mjs +95 -0
- package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +221 -0
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +195 -0
- package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +167 -0
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +10 -0
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +16 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +74 -15
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +9 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +5 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +13 -3
- package/src/runtime/agent/orchestrator/session/loop/usage.mjs +7 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-lifecycle-epoch.mjs +0 -8
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +44 -16
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +22 -5
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +39 -4
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +27 -5
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +55 -8
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +16 -0
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +3 -2
- package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/manager/workflow-switch-notice.mjs +58 -0
- package/src/runtime/agent/orchestrator/session/mixy-name.mjs +24 -0
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +32 -5
- package/src/runtime/agent/orchestrator/session/routine-result.d.mts +70 -0
- package/src/runtime/agent/orchestrator/session/routine-result.mjs +277 -0
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +8 -0
- package/src/runtime/agent/orchestrator/session/store-record-strict-scan.mjs +28 -9
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +16 -2
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +44 -12
- package/src/runtime/agent/orchestrator/session/store-summary-last-message.mjs +46 -0
- package/src/runtime/agent/orchestrator/session/store-summary-visibility.mjs +0 -4
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +44 -1
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +12 -0
- package/src/runtime/agent/orchestrator/tools/builtin/native-search-client.mjs +113 -5
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +4 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +25 -1
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +8 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +6 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +3 -0
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +75 -57
- package/src/runtime/browser-bridge/client.mjs +24 -0
- package/src/runtime/channels/lib/scheduler.mjs +40 -12
- package/src/runtime/channels/lib/schedules-db.mjs +71 -12
- package/src/runtime/channels/lib/webhook/session-dispatch.mjs +36 -16
- package/src/runtime/channels/lib/webhook.mjs +0 -1
- package/src/runtime/channels/lib/webhooks-db.mjs +100 -10
- package/src/runtime/channels/lib/worker-main.mjs +17 -20
- package/src/runtime/computer-bridge/client.mjs +28 -1
- package/src/runtime/connectors/gmail-app-password.mjs +690 -0
- package/src/runtime/connectors/google-mcp.mjs +446 -0
- package/src/runtime/memory/lib/core-memory-access.mjs +69 -0
- package/src/runtime/memory/lib/core-memory-file.mjs +16 -8
- package/src/runtime/memory/lib/core-memory-index.mjs +15 -9
- package/src/runtime/memory/lib/core-memory-management.mjs +10 -4
- package/src/runtime/memory/lib/core-memory-store.mjs +53 -30
- package/src/runtime/memory/lib/core-memory-uniqueness.mjs +10 -6
- package/src/runtime/memory/lib/http-router/session-routes.mjs +3 -2
- package/src/runtime/memory/lib/memory-action-handlers/core-actions.mjs +44 -14
- package/src/runtime/memory/lib/memory-schema/core-and-meta.mjs +11 -0
- package/src/runtime/memory/lib/memory.mjs +7 -1
- package/src/runtime/memory/lib/query-core-recall.mjs +9 -1
- package/src/runtime/memory/lib/query-hybrid-search.mjs +2 -0
- package/src/runtime/memory/lib/tool-call-handler.mjs +2 -0
- package/src/runtime/memory/tool-defs.mjs +5 -0
- package/src/runtime/shared/agent-avatar-sprites.mjs +445 -0
- package/src/runtime/shared/agent-avatar.d.mts +64 -0
- package/src/runtime/shared/agent-avatar.mjs +320 -0
- package/src/runtime/shared/agent-route-config.d.mts +3 -0
- package/src/runtime/shared/agent-route-config.mjs +16 -0
- package/src/runtime/shared/atomic-file.mjs +14 -1
- package/src/runtime/shared/config.mjs +8 -1
- package/src/runtime/shared/connector-accounts.mjs +15 -0
- package/src/runtime/shared/connector-catalog.d.mts +52 -0
- package/src/runtime/shared/connector-catalog.mjs +230 -0
- package/src/runtime/shared/connector-triggers.d.mts +3 -0
- package/src/runtime/shared/connector-triggers.mjs +43 -0
- package/src/runtime/shared/google-oauth-client.mjs +24 -0
- package/src/runtime/shared/held-request-host.d.mts +12 -0
- package/src/runtime/shared/held-request-host.mjs +71 -0
- package/src/runtime/shared/plain-preview.d.mts +1 -0
- package/src/runtime/shared/plain-preview.mjs +28 -0
- package/src/runtime/shared/routine-limits.d.mts +11 -0
- package/src/runtime/shared/routine-limits.mjs +21 -0
- package/src/runtime/shared/routine-trigger.d.mts +10 -0
- package/src/runtime/shared/routine-trigger.mjs +44 -0
- package/src/runtime/shared/schedule-model-ref.mjs +9 -10
- package/src/runtime/shared/slow-span.mjs +4 -12
- package/src/runtime/shared/statusline/statusline-segments.mjs +13 -1
- package/src/runtime/shared/transcript-metadata.mjs +10 -0
- package/src/runtime/shared/turn-changes.mjs +0 -8
- package/src/runtime/shared/usage-readout-totals.mjs +56 -0
- package/src/runtime/shared/user-data-guard.mjs +114 -36
- package/src/session-runtime/agent-home-delivery.mjs +459 -0
- package/src/session-runtime/agent-profile-changes.mjs +21 -0
- package/src/session-runtime/agent-room-delivery.mjs +92 -0
- package/src/session-runtime/agent-task-sessions.mjs +200 -0
- package/src/session-runtime/boot/apis.mjs +50 -18
- package/src/session-runtime/boot/facade.mjs +5 -8
- package/src/session-runtime/boot/infrastructure.mjs +28 -17
- package/src/session-runtime/boot/tools.mjs +3 -0
- package/src/session-runtime/channel-config-api.mjs +53 -5
- package/src/session-runtime/cwd-plugins/core-memory-context.mjs +36 -20
- package/src/session-runtime/cwd-plugins/plugin-status.mjs +6 -1
- package/src/session-runtime/held-requests.mjs +228 -0
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +121 -0
- package/src/session-runtime/internal-tool-executor/feature-tools.mjs +5 -1
- package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +31 -2
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +31 -2
- package/src/session-runtime/internal-tool-executor.mjs +2 -0
- package/src/session-runtime/lifecycle/session-catalog.mjs +9 -0
- package/src/session-runtime/lifecycle/session-switch/resume.mjs +4 -0
- package/src/session-runtime/lifecycle/shared.mjs +6 -0
- package/src/session-runtime/mcp-glue/server-catalog.mjs +8 -0
- package/src/session-runtime/mcp-glue/server-input.mjs +3 -0
- package/src/session-runtime/mcp-oauth-login.mjs +112 -15
- package/src/session-runtime/model-route/set-route.mjs +14 -3
- package/src/session-runtime/owned-automation-run.mjs +229 -0
- package/src/session-runtime/resource-api.mjs +5 -0
- package/src/session-runtime/resource-mcp-api.mjs +107 -13
- package/src/session-runtime/resource-skills-api.mjs +12 -0
- package/src/session-runtime/room-member-gate.mjs +48 -0
- package/src/session-runtime/routine-home-turn.mjs +156 -0
- package/src/session-runtime/routine-owner.mjs +48 -0
- package/src/session-runtime/schedule-session-run.mjs +30 -64
- package/src/session-runtime/services/agent-tool/helpers.mjs +10 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +19 -4
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +2 -0
- package/src/session-runtime/services/channel-admin.mjs +93 -24
- package/src/session-runtime/services/memory-access.mjs +37 -0
- package/src/session-runtime/services/provider-admin.mjs +74 -39
- package/src/session-runtime/services/schedule-access.mjs +91 -0
- package/src/session-runtime/session-create/session-options.mjs +34 -7
- package/src/session-runtime/session-hooks.mjs +16 -8
- package/src/session-runtime/setup-tool/executor.mjs +68 -6
- package/src/session-runtime/setup-tool/extended-actions.mjs +72 -14
- package/src/session-runtime/setup-tool/settings-contract.mjs +8 -6
- package/src/session-runtime/setup-tool/tool-defs.mjs +8 -0
- package/src/session-runtime/skills-api.mjs +16 -1
- package/src/session-runtime/tool-policy-refresh.mjs +238 -29
- package/src/session-runtime/turn/session-ops.mjs +8 -1
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +10 -2
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +3 -0
- package/src/session-runtime/webhook-session-run.mjs +49 -67
- package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +239 -0
- package/src/session-runtime/workflow-agents-api/agent-editor.mjs +556 -22
- package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +11 -1
- package/src/session-runtime/workflow-agents-api.mjs +4 -1
- package/src/standalone/daemon-agent-control.mjs +1 -8
- package/src/standalone/daemon-session-control.mjs +11 -2
- package/src/standalone/daemon.mjs +18 -4
- package/src/standalone/session-protocol.mjs +27 -0
- package/src/standalone/session-service/session-calls/session-turns.mjs +9 -0
- package/src/standalone/session-service.mjs +19 -0
- package/src/tui/app/slash-commands.mjs +20 -0
- package/src/tui/dist/index.mjs +164 -86
- package/src/tui/session/context-state.mjs +6 -1
- package/src/tui/session/notice-surface.mjs +35 -4
- package/src/tui/session/queue-helpers.mjs +2 -1
- package/src/tui/session/session-api/extensions.mjs +4 -0
- package/src/tui/session/session-api/intake/submission.mjs +5 -0
- package/src/tui/session/session-api/integrations.mjs +8 -0
- package/src/tui/session/session-api/lifecycle/session-reset.mjs +13 -3
- package/src/tui/session/session-api/lifecycle.mjs +17 -1
- package/src/tui/session/session-api/routes.mjs +48 -3
- package/src/tui/session/session-flow/drain.mjs +12 -3
- package/src/tui/session/session-flow/queue/entry-shape.mjs +2 -1
- package/src/tui/session/session-flow/queue/take-entries.mjs +3 -2
- package/src/tui/session/session-flow/steering.mjs +58 -24
- package/src/tui/session/tool-approval.mjs +26 -5
- package/src/tui/session/transcript-intake.mjs +6 -2
- package/src/tui/session/transcript-spill.mjs +5 -1
- package/src/tui/session/tui-steering-persist.mjs +65 -42
- package/src/tui/session/turn-live-call.mjs +56 -0
- package/src/tui/session/turn.mjs +22 -6
- package/src/session-runtime/automation-agents.mjs +0 -94
- package/src/session-runtime/automation-workflow.mjs +0 -59
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
// facade's hookCommonPayload / currentCwd accessor + the session itself. All
|
|
6
6
|
// properties are non-enumerable/configurable/writable so the loop/manager can
|
|
7
7
|
// read them by name without changing session enumeration.
|
|
8
|
+
import { roomMemberOfSession } from '../runtime/agent/orchestrator/session/agent-room.mjs';
|
|
9
|
+
import { roomMemberToolDecision } from './room-member-gate.mjs';
|
|
8
10
|
|
|
9
11
|
export function attachSessionHooks(session, { hooks, hookCommonPayload, getCwd }) {
|
|
10
12
|
const identity = (input) => ({
|
|
@@ -26,20 +28,26 @@ export function attachSessionHooks(session, { hooks, hookCommonPayload, getCwd }
|
|
|
26
28
|
// rejection cannot escape the tool loop or the compaction flow.
|
|
27
29
|
const dispatcher = (event, payload) => (input) => hooks.dispatch(event, hookCommonPayload(payload(input)));
|
|
28
30
|
|
|
29
|
-
// PreToolUse bridge.
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
// PreToolUse bridge. A group-room member's mutating calls always ask the
|
|
32
|
+
// user (room-member-gate.mjs), whatever the hooks decided short of a deny.
|
|
33
|
+
define('beforeToolHook', async (input, options = {}) => {
|
|
34
|
+
const name = input?.name || input?.tool_name;
|
|
35
|
+
const args = input?.args || input?.tool_input;
|
|
36
|
+
const cwd = input?.cwd || getCwd();
|
|
37
|
+
const decision = await hooks.beforeTool(
|
|
32
38
|
hookCommonPayload({
|
|
33
39
|
...input,
|
|
34
40
|
session_id: input?.sessionId || input?.session_id || session?.id,
|
|
35
|
-
tool_name:
|
|
36
|
-
tool_input:
|
|
41
|
+
tool_name: name,
|
|
42
|
+
tool_input: args,
|
|
37
43
|
tool_use_id: input?.toolCallId || input?.tool_use_id,
|
|
38
|
-
cwd
|
|
44
|
+
cwd,
|
|
39
45
|
}),
|
|
40
46
|
options
|
|
41
|
-
)
|
|
42
|
-
|
|
47
|
+
);
|
|
48
|
+
if (!roomMemberOfSession(session?.id)) return decision;
|
|
49
|
+
return roomMemberToolDecision({ name, args, cwd }, decision);
|
|
50
|
+
});
|
|
43
51
|
// PostToolUse: bridge runtime tool completions to the standard hook bus.
|
|
44
52
|
define('afterToolHook', dispatcher('PostToolUse', toolPayload));
|
|
45
53
|
// PostToolUseFailure: dispatched by loop.mjs only when a tool execution
|
|
@@ -9,6 +9,12 @@ import { INSTRUCTION_FILES_MODES } from '../../runtime/shared/instruction-files-
|
|
|
9
9
|
import { MEDIA_KINDS } from '../../runtime/media/tool-defs.mjs';
|
|
10
10
|
import { SETUP_DESKTOP_DOMAINS, SETUP_HANDOFFS } from './settings-contract.mjs';
|
|
11
11
|
import { executeExtendedSetupAction, publicAutomation, publicHookRule, validateMcpInput } from './extended-actions.mjs';
|
|
12
|
+
import {
|
|
13
|
+
assertAgentEditorAccess,
|
|
14
|
+
assertInteractiveCaller,
|
|
15
|
+
assertOwnAgentSettings,
|
|
16
|
+
scheduleCallerScope,
|
|
17
|
+
} from '../services/schedule-access.mjs';
|
|
12
18
|
import { SETUP_DESKTOP_UNCLAIMED, createSetupUiRequests } from './ui-requests.mjs';
|
|
13
19
|
import {
|
|
14
20
|
SETUP_ACTIONS,
|
|
@@ -20,8 +26,11 @@ import {
|
|
|
20
26
|
} from './tool-defs.mjs';
|
|
21
27
|
import { schemaValueError } from '../../runtime/shared/schema-value-error.mjs';
|
|
22
28
|
import { clean } from '../../runtime/agent/orchestrator/runtime-core/session-text.mjs';
|
|
29
|
+
import { CONNECTOR_IDS, connectorById } from '../../runtime/shared/connector-catalog.mjs';
|
|
23
30
|
import profileConfig from '../../runtime/shared/profile-config.cjs';
|
|
24
31
|
|
|
32
|
+
const AGENT_DEFINITION_ACTIONS = new Set(['create_definition', 'save_definition', 'delete_definition']);
|
|
33
|
+
|
|
25
34
|
const PROFILE_VALUE_IDS = Object.freeze({
|
|
26
35
|
language: profileConfig.PROFILE_LANGUAGES.map((entry) => entry.id),
|
|
27
36
|
experienceLevel: ['', ...profileConfig.PROFILE_EXPERIENCE_LEVELS.map((entry) => entry.id)],
|
|
@@ -35,6 +44,7 @@ const ACTION_APPLIES_TO = {
|
|
|
35
44
|
save_automation: 'the automation worker; scheduled runs follow the saved timing',
|
|
36
45
|
delete_automation: 'future automation runs',
|
|
37
46
|
set_automation_enabled: 'future automation runs',
|
|
47
|
+
run_automation: "one run now; its result posts into the owning agent's thread",
|
|
38
48
|
set_webhook_config: 'the webhook worker after configuration reload',
|
|
39
49
|
add_hook_rule: 'subsequent tool calls; no restart required',
|
|
40
50
|
set_hook_rule_enabled: 'subsequent tool calls; no restart required',
|
|
@@ -55,9 +65,10 @@ const OPEN_TARGET_HINTS = Object.freeze({
|
|
|
55
65
|
autoclear: 'Desktop: Settings → Context · TUI: /autoclear',
|
|
56
66
|
memory:
|
|
57
67
|
'Desktop: Extensions → Plugin → Built-in (Memory); core memories under Projects → project → Memories · TUI: /memory',
|
|
58
|
-
mcp: 'Desktop: Extensions →
|
|
59
|
-
skills: 'Desktop:
|
|
60
|
-
plugins:
|
|
68
|
+
mcp: 'Desktop: Extensions → Connectors tab · TUI: /mcp',
|
|
69
|
+
skills: 'Desktop: Skills (activity rail) · TUI: /skills',
|
|
70
|
+
plugins:
|
|
71
|
+
'Desktop: Extensions → Extensions tab (plugins that bring MCP servers: Connectors tab → Custom connectors) · TUI: /plugins',
|
|
61
72
|
update: 'Desktop: Settings → System → Update · TUI: /update',
|
|
62
73
|
usage: 'Desktop: /usage in the composer · TUI: /usage',
|
|
63
74
|
doctor: 'Desktop: Settings → System → Doctor, or /doctor in the composer · TUI: /doctor',
|
|
@@ -133,6 +144,7 @@ function publicProviderRows(setup) {
|
|
|
133
144
|
pick(row, {
|
|
134
145
|
reauthRequired: row.reauthRequired === true,
|
|
135
146
|
expiresAt: row.expiresAt || null,
|
|
147
|
+
plan: row.plan || null,
|
|
136
148
|
})
|
|
137
149
|
),
|
|
138
150
|
local: (setup?.local || []).map((row) =>
|
|
@@ -167,6 +179,7 @@ function configuredProviderRows(rows, accountCount) {
|
|
|
167
179
|
kind,
|
|
168
180
|
authenticated: row.authenticated,
|
|
169
181
|
status: row.status,
|
|
182
|
+
...(kind === 'oauth' ? { plan: row.plan || null } : {}),
|
|
170
183
|
...(row.reauthRequired ? { reauthRequired: true } : {}),
|
|
171
184
|
...accounts,
|
|
172
185
|
});
|
|
@@ -627,6 +640,25 @@ const SETUP_ACTION_HANDLERS = {
|
|
|
627
640
|
remove_plugin: async (rt, args) => ({
|
|
628
641
|
plugin: (await rt.removePlugin(requireText(args.name, 'name')))?.plugin || null,
|
|
629
642
|
}),
|
|
643
|
+
// The chat path of the one-click connect: the attached Desktop renders this
|
|
644
|
+
// call as a connect card (agent-chat connector card) that runs the same flow
|
|
645
|
+
// as Extensions → 커넥터. Nothing is connected here.
|
|
646
|
+
connect_connector: async (rt, args) => {
|
|
647
|
+
const entry = connectorById(requireText(args.connector, 'connector'));
|
|
648
|
+
if (!entry || entry.ownKey) throw new Error(`connector must be one of ${CONNECTOR_IDS.join(', ')}`);
|
|
649
|
+
const server = (rt.mcpStatus?.()?.servers || []).find((row) => row.connector === entry.id) || null;
|
|
650
|
+
const connected = entry.backend.kind === 'builtin' ? null : server?.connected === true;
|
|
651
|
+
return {
|
|
652
|
+
connector: entry.id,
|
|
653
|
+
name: entry.name,
|
|
654
|
+
backend: entry.backend.kind,
|
|
655
|
+
...(server ? { server: server.name } : {}),
|
|
656
|
+
connected,
|
|
657
|
+
note: connected
|
|
658
|
+
? `${entry.name} is already connected.`
|
|
659
|
+
: `A connect card for ${entry.name} is shown in this conversation; the user presses it (Desktop: Extensions → 커넥터). Check status mcp afterwards.`,
|
|
660
|
+
};
|
|
661
|
+
},
|
|
630
662
|
enable_plugin_mcp: async (rt, args) => {
|
|
631
663
|
const name = requireText(args.name, 'name');
|
|
632
664
|
const plugin = ((await rt.pluginsStatus())?.plugins || []).find((row) => row.name === name || row.id === name);
|
|
@@ -645,6 +677,7 @@ const READ_ONLY_SETUP_ACTIONS = new Set([
|
|
|
645
677
|
'open',
|
|
646
678
|
'list_models',
|
|
647
679
|
'get_mcp_server',
|
|
680
|
+
'connect_connector',
|
|
648
681
|
'read_definition',
|
|
649
682
|
'search_local_models',
|
|
650
683
|
'inspect_hf_model',
|
|
@@ -656,6 +689,7 @@ const BACKGROUND_SETUP_ACTIONS = new Set([
|
|
|
656
689
|
'maintain_local_model',
|
|
657
690
|
'cancel_local_installation',
|
|
658
691
|
'reconnect_mcp',
|
|
692
|
+
'run_automation',
|
|
659
693
|
]);
|
|
660
694
|
|
|
661
695
|
function setupMutationReceipt(action, result) {
|
|
@@ -671,7 +705,16 @@ function setupMutationReceipt(action, result) {
|
|
|
671
705
|
);
|
|
672
706
|
}
|
|
673
707
|
|
|
674
|
-
|
|
708
|
+
/** `getCallerSession(id)` returns the calling session's record (null when it
|
|
709
|
+
* cannot be resolved): automation actions authorize by its provenance. */
|
|
710
|
+
export function createSetupToolExecutor({
|
|
711
|
+
getApi,
|
|
712
|
+
getConfig,
|
|
713
|
+
notifySessionUi,
|
|
714
|
+
getSessionId,
|
|
715
|
+
getCallerSession,
|
|
716
|
+
flushSettings,
|
|
717
|
+
}) {
|
|
675
718
|
const desktop = createSetupUiRequests({ notifySessionUi, getSessionId });
|
|
676
719
|
const api = () => {
|
|
677
720
|
const facade = getApi?.();
|
|
@@ -701,12 +744,31 @@ export function createSetupToolExecutor({ getApi, getConfig, notifySessionUi, ge
|
|
|
701
744
|
};
|
|
702
745
|
}
|
|
703
746
|
|
|
704
|
-
async function execute(args, { signal }) {
|
|
747
|
+
async function execute(args, { signal, callerSessionId }) {
|
|
705
748
|
signal?.throwIfAborted();
|
|
706
749
|
const requestDesktop = (request) => desktop.request(request, { signal });
|
|
707
750
|
const action = validateSetupInput(args);
|
|
751
|
+
// The session that made this call, not just the runtime's own Lead.
|
|
752
|
+
const sessionId = clean(callerSessionId) || clean(getSessionId?.());
|
|
753
|
+
const caller = (sessionId && getCallerSession?.(sessionId)) || null;
|
|
754
|
+
// A headless run (schedule, webhook, delegated agent) only reads settings:
|
|
755
|
+
// it never creates agents, definitions or automations, nor changes any
|
|
756
|
+
// other setting. Hosts without session provenance (no getCallerSession)
|
|
757
|
+
// skip this gate; automation actions still refuse an unknown caller.
|
|
758
|
+
if (getCallerSession && !READ_ONLY_SETUP_ACTIONS.has(action)) {
|
|
759
|
+
const scope = scheduleCallerScope(caller);
|
|
760
|
+
assertInteractiveCaller(scope, action);
|
|
761
|
+
// Agent definitions (contacts) change only from Mixy; another agent's
|
|
762
|
+
// home changes only its own agent settings.
|
|
763
|
+
if (AGENT_DEFINITION_ACTIONS.has(action) && args.definitionKind === 'agent') {
|
|
764
|
+
assertAgentEditorAccess(scope, caller, action);
|
|
765
|
+
}
|
|
766
|
+
if (action === 'set_agent_route') assertOwnAgentSettings(scope, args.agent, action);
|
|
767
|
+
}
|
|
708
768
|
const rt = action === 'status' || action === 'open' ? null : api();
|
|
709
|
-
if (!Object.hasOwn(SETUP_ACTION_HANDLERS, action))
|
|
769
|
+
if (!Object.hasOwn(SETUP_ACTION_HANDLERS, action)) {
|
|
770
|
+
return executeExtendedSetupAction(rt, args, requestDesktop, { sessionId, caller });
|
|
771
|
+
}
|
|
710
772
|
return SETUP_ACTION_HANDLERS[action](rt, args, { requestDesktop, readStatus, openSurface });
|
|
711
773
|
}
|
|
712
774
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { SETUP_EXTENDED_PROPERTIES, SETUP_DESKTOP_ACTIONS } from './settings-contract.mjs';
|
|
2
2
|
import { MEDIA_KINDS } from '../../runtime/media/tool-defs.mjs';
|
|
3
3
|
import { OPENAI_COMPAT_PRESETS } from '../../runtime/agent/orchestrator/providers/openai-compat-presets.mjs';
|
|
4
|
+
import { agentIdOfHomeSession } from '../../runtime/agent/orchestrator/session/agent-home.mjs';
|
|
5
|
+
import { assertAutomationAccess, scheduleCallerScope } from '../services/schedule-access.mjs';
|
|
4
6
|
|
|
5
7
|
const own = (value, key) => Object.hasOwn(value || {}, key);
|
|
6
8
|
const pick = (value, keys) => Object.fromEntries(keys.filter((key) => own(value, key)).map((key) => [key, value[key]]));
|
|
@@ -203,6 +205,26 @@ async function saveDefinition(rt, args) {
|
|
|
203
205
|
return creating ? rt.addSkill(next) : rt.saveSkill({ ...next, originalName: current.originalName });
|
|
204
206
|
}
|
|
205
207
|
|
|
208
|
+
async function automationRow(rt, kind, name) {
|
|
209
|
+
const status = await rt.getChannelSetup();
|
|
210
|
+
return status[kind === 'schedule' ? 'schedules' : 'webhooks'].find((row) => row.name === name) || null;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/** Authorize one automation action for the calling session (`context.caller`,
|
|
214
|
+
* its session record; null when it could not be resolved) — schedule-access.mjs. */
|
|
215
|
+
async function authorizeAutomation(rt, context, { kind, action, current, owner = '' }) {
|
|
216
|
+
const scope = scheduleCallerScope(context.caller);
|
|
217
|
+
const transfer = String(owner ?? '').trim();
|
|
218
|
+
const agents = transfer && scope.kind === 'human' ? await rt.listAgents() : [];
|
|
219
|
+
assertAutomationAccess(scope, {
|
|
220
|
+
kind,
|
|
221
|
+
action,
|
|
222
|
+
current,
|
|
223
|
+
owner: transfer,
|
|
224
|
+
agentIds: (Array.isArray(agents) ? agents : []).map((agent) => agent?.id).filter(Boolean),
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
|
|
206
228
|
export const EXTENDED_SETUP_HANDLERS = Object.freeze({
|
|
207
229
|
set_local_context: (rt, args) => rt.setLocalProviderContext(args.modelId, args.localContextWindow),
|
|
208
230
|
async list_models(rt, args) {
|
|
@@ -238,22 +260,29 @@ export const EXTENDED_SETUP_HANDLERS = Object.freeze({
|
|
|
238
260
|
return {
|
|
239
261
|
...result,
|
|
240
262
|
recovery:
|
|
241
|
-
|
|
263
|
+
args.definitionKind === 'workflow'
|
|
264
|
+
? 'User-authored definition files are deleted. A built-in override may revert to its built-in definition.'
|
|
265
|
+
: 'A custom agent or bot is archived with its chat and its routines are switched off; the user can restore it from Sessions → Archived, or delete it there for good. A built-in override reverts to its built-in definition.',
|
|
242
266
|
};
|
|
243
267
|
},
|
|
244
|
-
async save_automation(rt, args) {
|
|
268
|
+
async save_automation(rt, args, context = {}) {
|
|
245
269
|
const kind = args.automationKind;
|
|
246
270
|
const input = args.entry;
|
|
247
271
|
if (kind === 'webhook' && ['time', 'at', 'timezone', 'days'].some((key) => own(input, key))) {
|
|
248
|
-
throw new Error('Schedule timing
|
|
272
|
+
throw new Error('Schedule fields (timing) are not accepted for webhooks');
|
|
249
273
|
}
|
|
250
274
|
if (kind === 'schedule' && own(input, 'parser')) throw new Error('parser is a webhook-only field');
|
|
251
275
|
let previous = {};
|
|
252
276
|
if (input.overwrite) {
|
|
253
|
-
|
|
254
|
-
previous = status[kind === 'schedule' ? 'schedules' : 'webhooks'].find((row) => row.name === input.name);
|
|
277
|
+
previous = await automationRow(rt, kind, input.name);
|
|
255
278
|
if (!previous) throw new Error(`${kind} "${input.name}" does not exist`);
|
|
256
279
|
}
|
|
280
|
+
await authorizeAutomation(rt, context, {
|
|
281
|
+
kind,
|
|
282
|
+
action: input.overwrite ? 'edit' : 'create',
|
|
283
|
+
current: input.overwrite ? previous : null,
|
|
284
|
+
owner: input.owner,
|
|
285
|
+
});
|
|
257
286
|
const next = { ...pick(previous, entryKeys), ...input };
|
|
258
287
|
if (kind === 'schedule') {
|
|
259
288
|
if (previous.whenAt && !own(input, 'time') && !own(input, 'at')) {
|
|
@@ -263,6 +292,11 @@ export const EXTENDED_SETUP_HANDLERS = Object.freeze({
|
|
|
263
292
|
if (own(input, 'time') && !own(input, 'at')) delete next.at;
|
|
264
293
|
if (own(input, 'at') && !own(input, 'time')) delete next.time;
|
|
265
294
|
}
|
|
295
|
+
// An automation created from an agent's home thread belongs to that agent.
|
|
296
|
+
if (!input.overwrite && !own(input, 'owner')) {
|
|
297
|
+
const homeAgent = agentIdOfHomeSession(context.sessionId);
|
|
298
|
+
if (homeAgent) next.owner = homeAgent;
|
|
299
|
+
}
|
|
266
300
|
const result = kind === 'schedule' ? await rt.saveSchedule(next) : await rt.saveWebhook(next);
|
|
267
301
|
return {
|
|
268
302
|
...publicAutomation(result),
|
|
@@ -275,18 +309,42 @@ export const EXTENDED_SETUP_HANDLERS = Object.freeze({
|
|
|
275
309
|
: {}),
|
|
276
310
|
};
|
|
277
311
|
},
|
|
278
|
-
async delete_automation(rt, args) {
|
|
279
|
-
const
|
|
280
|
-
|
|
281
|
-
|
|
312
|
+
async delete_automation(rt, args, context = {}) {
|
|
313
|
+
const current = await automationRow(rt, args.automationKind, args.name);
|
|
314
|
+
if (!current) throw new Error('Automation entry not found');
|
|
315
|
+
await authorizeAutomation(rt, context, { kind: args.automationKind, action: 'delete', current });
|
|
282
316
|
const result =
|
|
283
317
|
args.automationKind === 'schedule' ? await rt.deleteSchedule(args.name) : await rt.deleteWebhook(args.name);
|
|
284
318
|
return { ...result, recovery: 'The automation record is deleted; recreating it requires its definition.' };
|
|
285
319
|
},
|
|
286
|
-
set_automation_enabled
|
|
287
|
-
args.automationKind
|
|
320
|
+
async set_automation_enabled(rt, args, context = {}) {
|
|
321
|
+
const current = await automationRow(rt, args.automationKind, args.name);
|
|
322
|
+
if (!current) throw new Error('Automation entry not found');
|
|
323
|
+
const action = args.enabled === false ? 'pause' : 'resume';
|
|
324
|
+
await authorizeAutomation(rt, context, { kind: args.automationKind, action, current });
|
|
325
|
+
return args.automationKind === 'schedule'
|
|
288
326
|
? rt.setScheduleEnabled(args.name, args.enabled)
|
|
289
|
-
: rt.setWebhookEnabled(args.name, args.enabled)
|
|
327
|
+
: rt.setWebhookEnabled(args.name, args.enabled);
|
|
328
|
+
},
|
|
329
|
+
// Starts the run and returns at once: the run is its own session, and its
|
|
330
|
+
// result posts into the owning agent's thread when it ends. A webhook
|
|
331
|
+
// re-runs on its latest received payload.
|
|
332
|
+
async run_automation(rt, args, context = {}) {
|
|
333
|
+
const kind = args.automationKind;
|
|
334
|
+
const current = await automationRow(rt, kind, args.name);
|
|
335
|
+
if (!current) throw new Error('Automation entry not found');
|
|
336
|
+
await authorizeAutomation(rt, context, { kind, action: 'run', current });
|
|
337
|
+
if (kind === 'webhook' && current.hasLastPayload !== true) {
|
|
338
|
+
throw new Error(`webhook "${args.name}" has not received a payload yet`);
|
|
339
|
+
}
|
|
340
|
+
const run = kind === 'webhook' ? rt.runWebhookNow(args.name) : rt.runScheduleNow(args.name);
|
|
341
|
+
void Promise.resolve(run).catch(() => {});
|
|
342
|
+
return {
|
|
343
|
+
name: args.name,
|
|
344
|
+
started: true,
|
|
345
|
+
note: "The run is its own session; its result posts into the owning agent's thread when it finishes.",
|
|
346
|
+
};
|
|
347
|
+
},
|
|
290
348
|
async set_developer_option(rt, args) {
|
|
291
349
|
const option = rt
|
|
292
350
|
.getDeveloperSettings()
|
|
@@ -360,9 +418,9 @@ function hookRuleAt(rt, index) {
|
|
|
360
418
|
return publicHookRule(rule);
|
|
361
419
|
}
|
|
362
420
|
|
|
363
|
-
export async function executeExtendedSetupAction(rt, args, requestDesktop) {
|
|
421
|
+
export async function executeExtendedSetupAction(rt, args, requestDesktop, context = {}) {
|
|
364
422
|
if (SETUP_DESKTOP_ACTIONS.includes(args.action)) return requestDesktop(args);
|
|
365
423
|
const handler = EXTENDED_SETUP_HANDLERS[args.action];
|
|
366
424
|
if (!handler) throw new Error(`setup: unhandled action "${args.action}"`);
|
|
367
|
-
return handler(rt, args);
|
|
425
|
+
return handler(rt, args, context);
|
|
368
426
|
}
|
|
@@ -26,6 +26,7 @@ export const SETUP_EXTENDED_ACTION_FIELDS = Object.freeze({
|
|
|
26
26
|
save_automation: 'automationKind entry',
|
|
27
27
|
delete_automation: 'automationKind name',
|
|
28
28
|
set_automation_enabled: 'automationKind name enabled',
|
|
29
|
+
run_automation: 'automationKind name',
|
|
29
30
|
set_webhook_config: 'webhook',
|
|
30
31
|
set_desktop_settings: 'desktop',
|
|
31
32
|
set_appearance: 'appearance',
|
|
@@ -51,6 +52,7 @@ export const SETUP_ACTIVITY_RAIL_PIN_IDS = Object.freeze([
|
|
|
51
52
|
'workflows',
|
|
52
53
|
'projects',
|
|
53
54
|
'extensions',
|
|
55
|
+
'skills',
|
|
54
56
|
'source-control',
|
|
55
57
|
'search',
|
|
56
58
|
'webhooks',
|
|
@@ -172,13 +174,7 @@ export const SETUP_EXTENDED_PROPERTIES = Object.freeze({
|
|
|
172
174
|
timezone: text,
|
|
173
175
|
days: { ...text, description: 'Schedule day selector, e.g. weekdays or mon,wed,fri.' },
|
|
174
176
|
parser: { type: 'string', enum: ['github', 'generic', 'stripe', 'sentry'] },
|
|
175
|
-
model: {
|
|
176
|
-
...text,
|
|
177
|
-
description:
|
|
178
|
-
'Required for new schedules; no default-model fallback. Use provider/model[@effort][+fast][+noauto][?parameter=value] (+noauto: Auto reasoning off; absent = on) or an existing preset name. On overwrite, omission preserves the saved model, which must be non-empty.',
|
|
179
|
-
},
|
|
180
177
|
cwd: text,
|
|
181
|
-
workflow: text,
|
|
182
178
|
attachments: {
|
|
183
179
|
type: 'array',
|
|
184
180
|
maxItems: 8,
|
|
@@ -197,6 +193,11 @@ export const SETUP_EXTENDED_PROPERTIES = Object.freeze({
|
|
|
197
193
|
),
|
|
198
194
|
},
|
|
199
195
|
enabled: boolean,
|
|
196
|
+
owner: {
|
|
197
|
+
...text,
|
|
198
|
+
description:
|
|
199
|
+
"The bot id that owns the schedule or webhook; each run is a turn in that bot's chat, where it replies with the result. The bot must exist (no representative bot yet = refused). New entries default to the bot of the calling thread (the representative bot = lead); on overwrite, omission keeps the owner.",
|
|
200
|
+
},
|
|
200
201
|
overwrite: { ...boolean, description: 'Explicitly update an existing entry; omitted fields are preserved.' },
|
|
201
202
|
},
|
|
202
203
|
['name']
|
|
@@ -213,6 +214,7 @@ export const SETUP_EXTENDED_PROPERTIES = Object.freeze({
|
|
|
213
214
|
usagePinned: boolean,
|
|
214
215
|
usageRailShortLong: boolean,
|
|
215
216
|
computerObserveOnly: boolean,
|
|
217
|
+
browserAutoSignIn: boolean,
|
|
216
218
|
notificationVolume: {
|
|
217
219
|
type: 'integer',
|
|
218
220
|
minimum: 0,
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
import { MEDIA_KINDS } from '../../runtime/media/tool-defs.mjs';
|
|
8
8
|
import { INSTRUCTION_FILES_MODES } from '../../runtime/shared/instruction-files-mode.mjs';
|
|
9
9
|
import { WORKTREE_NEW_TASK_DEFAULTS } from '../../runtime/shared/worktrees/settings.mjs';
|
|
10
|
+
import { CONNECTOR_IDS } from '../../runtime/shared/connector-catalog.mjs';
|
|
10
11
|
|
|
11
12
|
/** Built-in `setup` tool: the model's handle on a Mixdog user's persisted
|
|
12
13
|
* configuration. The description is a contract only; how to use each action
|
|
@@ -110,6 +111,7 @@ export const SETUP_ACTION_FIELDS = Object.freeze({
|
|
|
110
111
|
set_plugin_enabled: 'name enabled',
|
|
111
112
|
remove_plugin: 'name',
|
|
112
113
|
enable_plugin_mcp: 'name',
|
|
114
|
+
connect_connector: 'connector',
|
|
113
115
|
set_worktree_settings: 'worktree',
|
|
114
116
|
...SETUP_EXTENDED_ACTION_FIELDS,
|
|
115
117
|
});
|
|
@@ -345,6 +347,12 @@ export const SETUP_TOOL_DEFS = Object.freeze([
|
|
|
345
347
|
description: 'set_disabled_skills: full list of disabled skill names.',
|
|
346
348
|
},
|
|
347
349
|
source: { type: 'string', description: 'add_plugin: Git URL, owner/repo, or local path.' },
|
|
350
|
+
connector: {
|
|
351
|
+
type: 'string',
|
|
352
|
+
enum: [...CONNECTOR_IDS],
|
|
353
|
+
description:
|
|
354
|
+
'connect_connector: catalog service to connect. Shows the user a connect card in this conversation (one-click sign-in or a key sheet in Desktop); it never connects by itself.',
|
|
355
|
+
},
|
|
348
356
|
kind: {
|
|
349
357
|
type: 'string',
|
|
350
358
|
enum: ['skills', 'mcp', 'plugins', ...MEDIA_KINDS],
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Skill surface (status listing, resource load, tool envelope, global skill
|
|
2
2
|
// creation/editing). The runtime facade only wires the mutable cwd and the
|
|
3
3
|
// context module into it.
|
|
4
|
-
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
|
|
4
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs';
|
|
5
5
|
import { basename, dirname, isAbsolute, join, relative, resolve } from 'node:path';
|
|
6
6
|
import { resolvePluginData } from '../runtime/shared/plugin-paths.mjs';
|
|
7
7
|
import {
|
|
@@ -193,6 +193,20 @@ export function createSkillsApi({ contextMod, getCwd, getTools = () => [] }) {
|
|
|
193
193
|
return { originalName, name, filePath };
|
|
194
194
|
}
|
|
195
195
|
|
|
196
|
+
function removeGlobalSkill(input = {}) {
|
|
197
|
+
const name = validateSkillName(input.name);
|
|
198
|
+
const resource = contextMod.loadSkillResource?.(name, getCwd());
|
|
199
|
+
if (!resource?.filePath) throw new Error(`skill not found: ${name}`);
|
|
200
|
+
const dir = dirname(resolve(resource.filePath));
|
|
201
|
+
const rel = relative(globalSkillsRoot(), dir);
|
|
202
|
+
if (!rel || rel.startsWith('..') || isAbsolute(rel) || basename(dir) !== name) {
|
|
203
|
+
throw new Error(`only your own skills can be removed: ${name}`);
|
|
204
|
+
}
|
|
205
|
+
rmSync(dir, { recursive: true, force: true });
|
|
206
|
+
invalidateSkills();
|
|
207
|
+
return { name };
|
|
208
|
+
}
|
|
209
|
+
|
|
196
210
|
function invalidateSkills() {
|
|
197
211
|
contextMod.invalidateSkillsCache?.(getCwd());
|
|
198
212
|
}
|
|
@@ -203,6 +217,7 @@ export function createSkillsApi({ contextMod, getCwd, getTools = () => [] }) {
|
|
|
203
217
|
skillToolContent,
|
|
204
218
|
addGlobalSkill,
|
|
205
219
|
saveSkillDocument,
|
|
220
|
+
removeGlobalSkill,
|
|
206
221
|
invalidateSkills,
|
|
207
222
|
};
|
|
208
223
|
}
|