diff --git a/cli/src/commands/import/studio-app/index.ts b/cli/src/commands/import/studio-app/index.ts index a3f9c51d003..2615322807d 100644 --- a/cli/src/commands/import/studio-app/index.ts +++ b/cli/src/commands/import/studio-app/index.ts @@ -1,3 +1,4 @@ +import type { CommandEffect } from '@/framework/command' import { DifyCommand } from '@/commands/_shared/dify-command' import { httpRetryFlag } from '@/commands/_shared/global-flags' import { Flags } from '@/framework/flags' @@ -7,6 +8,8 @@ import { pluginDependencyLabel, runImportApp } from './run' export default class ImportStudioApp extends DifyCommand { static override description = 'Import a studio app from a DSL YAML file or URL' + static override effect: CommandEffect = 'write' + static override examples = [ '<%= config.bin %> import studio-app --from-file ./app.yaml', '<%= config.bin %> import studio-app --from-file /path/to/app.yaml --name "My App"', diff --git a/cli/src/commands/use/account/index.ts b/cli/src/commands/use/account/index.ts index 182c39b51d5..2ecd1b1556a 100644 --- a/cli/src/commands/use/account/index.ts +++ b/cli/src/commands/use/account/index.ts @@ -1,3 +1,4 @@ +import type { CommandEffect } from '@/framework/command' import { DifyCommand } from '@/commands/_shared/dify-command' import { Flags } from '@/framework/flags' import { realStreams } from '@/sys/io/streams' @@ -6,6 +7,8 @@ import { runUseAccount } from './use-account' export default class UseAccount extends DifyCommand { static override description = 'Switch the active account on the current host' + static override effect: CommandEffect = 'write' + static override examples = [ '<%= config.bin %> use account', '<%= config.bin %> use account --email bob@corp.com', diff --git a/cli/src/commands/use/host/index.ts b/cli/src/commands/use/host/index.ts index bfd97626947..7118fbbe7b7 100644 --- a/cli/src/commands/use/host/index.ts +++ b/cli/src/commands/use/host/index.ts @@ -1,3 +1,4 @@ +import type { CommandEffect } from '@/framework/command' import { DifyCommand } from '@/commands/_shared/dify-command' import { Flags } from '@/framework/flags' import { realStreams } from '@/sys/io/streams' @@ -6,6 +7,8 @@ import { runUseHost } from './use-host' export default class UseHost extends DifyCommand { static override description = 'Switch the active Dify host' + static override effect: CommandEffect = 'write' + static override examples = [ '<%= config.bin %> use host', '<%= config.bin %> use host --domain cloud.dify.ai', diff --git a/cli/test/e2e/suites/agent/agent-skill-workflow.e2e.ts b/cli/test/e2e/suites/agent/agent-skill-workflow.e2e.ts index 8f3702d1b75..b9e972336c7 100644 --- a/cli/test/e2e/suites/agent/agent-skill-workflow.e2e.ts +++ b/cli/test/e2e/suites/agent/agent-skill-workflow.e2e.ts @@ -583,6 +583,18 @@ describe('E2E / agent skill — effect guard (no auth)', () => { expect(JSON.parse(r.stdout).effect).toBe('write') }) + it('[P0] state-mutating import and context switches have effect=write', async () => { + for (const args of [ + ['help', 'import', 'studio-app', '-o', 'json'], + ['help', 'use', 'account', '-o', 'json'], + ['help', 'use', 'host', '-o', 'json'], + ]) { + const r = await run(args) + expect(r.exitCode).toBe(0) + expect(JSON.parse(r.stdout).effect).toBe('write') + } + }) + it('[P0] auth devices revoke effect=destructive — agent must confirm before calling', async () => { const r = await run(['help', 'auth', 'devices', 'revoke', '-o', 'json']) expect(r.exitCode).toBe(0)