@xdxer/dingtalk-agent 0.1.5-beta.1 → 0.1.5-beta.10
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 +201 -0
- package/README.en.md +99 -66
- package/README.md +99 -66
- package/dist/bin/dingtalk-agent.js +735 -149
- package/dist/bin/dingtalk-agent.js.map +1 -1
- package/dist/src/actions.js +3 -2
- package/dist/src/actions.js.map +1 -1
- package/dist/src/agent-audit.js +202 -85
- package/dist/src/agent-audit.js.map +1 -1
- package/dist/src/agent-definition.js +7 -3
- package/dist/src/agent-definition.js.map +1 -1
- package/dist/src/agent-enhance.js +51 -32
- package/dist/src/agent-enhance.js.map +1 -1
- package/dist/src/agent-platform.js +3 -3
- package/dist/src/agent-platform.js.map +1 -1
- package/dist/src/bootstrap.js +6 -2
- package/dist/src/bootstrap.js.map +1 -1
- package/dist/src/development-workspace.js +210 -34
- package/dist/src/development-workspace.js.map +1 -1
- package/dist/src/doctor.js +65 -9
- package/dist/src/doctor.js.map +1 -1
- package/dist/src/dws.js +67 -3
- package/dist/src/dws.js.map +1 -1
- package/dist/src/init.js +2 -1
- package/dist/src/init.js.map +1 -1
- package/dist/src/memory/noop-receipt.js +306 -0
- package/dist/src/memory/noop-receipt.js.map +1 -0
- package/dist/src/memory/operational.js +27 -3
- package/dist/src/memory/operational.js.map +1 -1
- package/dist/src/memory/remote-state.js +2 -1
- package/dist/src/memory/remote-state.js.map +1 -1
- package/dist/src/multica-deploy.js +692 -125
- package/dist/src/multica-deploy.js.map +1 -1
- package/dist/src/multica-provider.js +303 -25
- package/dist/src/multica-provider.js.map +1 -1
- package/dist/src/multica-runtime-vocabulary.js +110 -0
- package/dist/src/multica-runtime-vocabulary.js.map +1 -0
- package/dist/src/opencode-evals.js +6 -6
- package/dist/src/opencode-evals.js.map +1 -1
- package/dist/src/opencode-provider.js +21 -7
- package/dist/src/opencode-provider.js.map +1 -1
- package/dist/src/opencode-workspace.js +3 -3
- package/dist/src/opencode-workspace.js.map +1 -1
- package/dist/src/personal-event-evals.js +4 -2
- package/dist/src/personal-event-evals.js.map +1 -1
- package/dist/src/promotion.js +2 -1
- package/dist/src/promotion.js.map +1 -1
- package/dist/src/remote-semantic-state-live-evals.js +14 -8
- package/dist/src/remote-semantic-state-live-evals.js.map +1 -1
- package/dist/src/remote-state-evals.js +2 -2
- package/dist/src/remote-state-evals.js.map +1 -1
- package/dist/src/robot-evals.js +3 -3
- package/dist/src/robot-evals.js.map +1 -1
- package/dist/src/schedule-plan.js +380 -0
- package/dist/src/schedule-plan.js.map +1 -0
- package/dist/src/sessions.js +1 -1
- package/dist/src/sessions.js.map +1 -1
- package/dist/src/skill-manager.js +145 -13
- package/dist/src/skill-manager.js.map +1 -1
- package/dist/src/skills.js +2 -0
- package/dist/src/skills.js.map +1 -1
- package/dist/src/tui.js +369 -0
- package/dist/src/tui.js.map +1 -0
- package/dist/src/upgrade.js +113 -33
- package/dist/src/upgrade.js.map +1 -1
- package/dist/src/waits.js +2 -1
- package/dist/src/waits.js.map +1 -1
- package/dist/src/workspace.js +12 -7
- package/dist/src/workspace.js.map +1 -1
- package/docs/AGENT-IN-PRODUCTION.md +255 -0
- package/docs/ARCHITECTURE.md +165 -31
- package/docs/INSTALLATION.md +7 -7
- package/docs/PLATFORM-GUARDRAILS.md +188 -0
- package/docs/PRIOR-ART.md +4 -0
- package/docs/SELF-TEST.md +4 -4
- package/docs/architecture/agent-platform-connection-layer.svg +120 -0
- package/docs/architecture/digital-employee-composition.svg +92 -0
- package/docs/architecture/dingtalk-agent-architecture.svg +125 -0
- package/docs/assets/digital-employee-at-work.svg +77 -0
- package/docs/schemas/multica-deployment-plan.schema.json +3 -1
- package/docs/schemas/multica-deployment-receipt.schema.json +17 -3
- package/docs/schemas/multica-deployment-status.schema.json +6 -2
- package/docs/schemas/multica-workspace-inspection.schema.json +16 -0
- package/docs/schemas/multica-workspace-run-plan.schema.json +31 -0
- package/docs/schemas/multica-workspace-run.schema.json +161 -0
- package/docs/schemas/multica-workspace-status.schema.json +2 -0
- package/docs/schemas/project.schema.json +54 -3
- package/docs/schemas/workspace-scaffold.schema.json +38 -0
- package/examples/agents/README.md +10 -8
- package/examples/agents/fde-coach/AGENTS.md +2 -34
- package/examples/agents/fde-coach/agent/AGENTS.md +35 -0
- package/examples/agents/fde-coach/agent.bindings.json +10 -0
- package/examples/agents/release-manager/AGENTS.md +2 -34
- package/examples/agents/release-manager/agent/AGENTS.md +35 -0
- package/examples/agents/release-manager/agent.bindings.json +10 -0
- package/lab/agent-eval/catalog.json +5 -5
- package/lab/agent-eval/classic-failures.json +4 -4
- package/lab/agent-eval/completion-gate-regression.json +9 -9
- package/lab/agent-eval/personal-event-live.example.json +3 -3
- package/lab/agent-eval/remote-semantic-state-live.example.json +1 -1
- package/lab/agent-eval/workspace/opencode.json +2 -2
- package/lab/project-workspace/fake-multica-provider.mjs +171 -17
- package/lab/project-workspace/multica-deploy.fixture.json +2 -2
- package/lab/project-workspace/multica-readonly.fixture.json +4 -16
- package/lab/project-workspace/opencode-provider-suite.json +3 -3
- package/lab/project-workspace/project.fixture.json +2 -6
- package/lab/robot-eval/suite.json +1 -1
- package/lab/robot-eval/workspace/AGENTS.md +1 -1
- package/lab/robot-eval/workspace/opencode.json +2 -2
- package/lab/schemas/personal-event-eval.schema.json +1 -1
- package/package.json +12 -9
- package/skills/README.md +10 -8
- package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/SKILL.md +48 -23
- package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/assets/AGENTS.template.md +1 -1
- package/skills/core/dta-agent-compose/assets/REPOSITORY.template.md +10 -0
- package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/assets/agent.bindings.dingtalk-doc.template.json +2 -2
- package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/assets/agent.bindings.local.template.json +2 -2
- package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/assets/hosts/opencode/opencode.template.json +3 -2
- package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/evals/evals.json +4 -4
- package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/references/agent-definition-contract.md +7 -7
- package/skills/core/dta-agent-compose/references/drive-and-schedules.md +166 -0
- package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/references/host-loading-contract.md +11 -13
- package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/references/hosts/claude-code.md +13 -12
- package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/references/hosts/opencode.md +14 -13
- package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/SKILL.md +2 -2
- package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/assets/eval-catalog.template.json +1 -1
- package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/evals/evals.json +1 -1
- package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/references/eval-topology.md +3 -3
- package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/references/interactive-debug-channels.md +10 -4
- package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/SKILL.md +21 -5
- package/skills/core/dta-basic-behavior/references/event-to-behavior.md +38 -0
- package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/references/memory-and-evolution.md +3 -1
- package/skills/core/dta-basic-behavior/references/perception-and-gates.md +87 -0
- package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/references/risk-authority-and-privacy.md +12 -0
- package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/references/truth-and-recovery.md +4 -2
- package/skills/core/dta-people-group-memory/COMPLETENESS.md +36 -0
- package/skills/core/dta-people-group-memory/SKILL.md +69 -0
- package/skills/core/dta-people-group-memory/references/adapters.md +273 -0
- package/skills/core/dta-people-group-memory/references/assembly-guidance.md +40 -0
- package/skills/core/dta-people-group-memory/references/binding.md +110 -0
- package/skills/core/dta-people-group-memory/references/cold-start.md +70 -0
- package/skills/core/dta-people-group-memory/references/config-binding.md +89 -0
- package/skills/core/dta-people-group-memory/references/consent-and-visibility.md +83 -0
- package/skills/core/dta-people-group-memory/references/consolidation.md +162 -0
- package/skills/core/dta-people-group-memory/references/event-ingest.md +103 -0
- package/skills/core/dta-people-group-memory/references/guided-setup.md +70 -0
- package/skills/core/dta-people-group-memory/references/model.md +148 -0
- package/skills/core/dta-people-group-memory/references/storage-port.md +107 -0
- package/skills/platforms/deap/PLATFORM.md +30 -1
- package/skills/platforms/multica-dingtalk/PLATFORM.md +34 -8
- package/skills/platforms/multica-dingtalk/{dingtalk-agent-deploy-multica → dta-deploy-multica}/SKILL.md +10 -8
- package/skills/platforms/multica-dingtalk/dta-deploy-multica/references/multica-deployment-contract.md +67 -0
- package/skills/platforms/multica-dingtalk/{multica-external → dta-ops-multica}/SKILL.md +81 -11
- package/skills/platforms/multica-dingtalk/{multica-external → dta-ops-multica}/scripts/bootstrap.sh +2 -2
- package/skills/platforms/multica-dingtalk/{multica-external → dta-ops-multica}/scripts/multica_ext.py +264 -16
- package/docs/assets/agent-delivery-lifecycle.svg +0 -103
- package/skills/core/dingtalk-basic-behavior/references/event-to-behavior.md +0 -24
- package/skills/core/dingtalk-basic-behavior/references/perception-and-gates.md +0 -28
- package/skills/platforms/multica-dingtalk/dingtalk-agent-boot-multica/SKILL.md +0 -40
- package/skills/platforms/multica-dingtalk/dingtalk-agent-deploy-multica/references/multica-deployment-contract.md +0 -49
- /package/examples/agents/fde-coach/{skills → agent/skills}/fde-coach/SKILL.md +0 -0
- /package/examples/agents/release-manager/{skills → agent/skills}/release-manager/SKILL.md +0 -0
- /package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/assets/role-skill.template.md +0 -0
- /package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/references/storage-routing.md +0 -0
- /package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/references/evidence-contract.md +0 -0
- /package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/references/failure-to-case.md +0 -0
- /package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/references/local-connector-smoke.md +0 -0
- /package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/references/scenario-taxonomy.md +0 -0
- /package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/references/storage-modes.md +0 -0
- /package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/assets/memory-candidate-proposal.json +0 -0
- /package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/assets/task-checkpoint.json +0 -0
- /package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/references/action-contract.md +0 -0
- /package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/references/runtime-modes.md +0 -0
- /package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/references/task-lifecycle.md +0 -0
- /package/skills/platforms/multica-dingtalk/{dingtalk-agent-deploy-multica → dta-deploy-multica}/references/promotion-observation-contract.md +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/bootstrap.ts"],"names":[],"mappings":"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","sourcesContent":["// Agent Session 的轻量水合入口。\n//\n// 它不要求 init,也不创建项目模板:\n// - local-dir 直接返回可读的 Markdown 挂载;\n// - dingtalk-doc 通过 DWS 拉成隐藏的只读快照;\n// - 已有 workspace@1 时复用其中的 mounts。\n\nimport {\n existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, realpathSync, renameSync,\n writeFileSync,\n} from 'node:fs'\nimport { basename, dirname, join, relative, resolve } from 'node:path'\nimport { digest } from './events.js'\nimport * as dws from './dws.js'\nimport { buildBootstrapDefinition } from './agent-definition.js'\nimport { directInvocation } from './invocation.js'\nimport type { AgentDefinition, InvocationContext } from './types.js'\nimport { loadWorkspace, workspacePath, type WorkspaceSpec } from './workspace.js'\n\ntype Provider = 'local-dir' | 'local-md' | 'dingtalk-doc'\n\nexport interface BootstrapOptions {\n agent?: string\n storage?: string\n memory?: string\n knowledge?: string\n skills?: string\n artifacts?: string\n stateDir?: string\n profile?: string\n expectedUserId?: string\n /** Inspect bindings without reading a remote provider. Used by the local agent audit. */\n deferRemote?: boolean\n context?: Partial<{\n agent: string\n memory: string\n knowledge: string\n skills: string\n artifacts: string\n stateDir: string\n profile: string\n expectedUserId: string\n }>\n}\n\nexport interface BootstrapMount {\n slot: string\n provider: Provider\n source: string\n path: string\n hash: string\n}\n\nexport interface BootstrapResult {\n $schema: 'dingtalk-agent/bootstrap@1'\n mode: 'direct' | 'workspace'\n initialized: boolean\n scopeId: string\n contextId: string\n storage: string\n stateDir: string\n mounts: BootstrapMount[]\n definition: AgentDefinition\n invocation: InvocationContext\n note: string\n}\n\nexport function bootstrap(root: string, options: BootstrapOptions = {}): BootstrapResult {\n // Canonicalize aliases such as macOS /var -> /private/var so bootstrap,\n // agent audit, evidence fingerprints, and later Session snapshots hash the\n // same Agent root.\n const cwd = realpathSync(resolve(root))\n const hasWorkspace = existsSync(workspacePath(cwd))\n const workspace = hasWorkspace ? loadWorkspace(cwd) : null\n const agent = select(\n options.agent || options.storage, options.context?.agent, process.env.DTA_AGENT_SOURCE,\n workspace ? 'workspace-manifest' : '', `local-dir:${cwd}`,\n )\n const memory = select(\n options.memory, options.context?.memory, process.env.DTA_MEMORY_STORAGE,\n workspace?.mounts.memory || '', existsSync(join(cwd, 'MEMORY.md')) ? 'local-md:MEMORY.md' : '',\n )\n const knowledge = select(\n options.knowledge, options.context?.knowledge, process.env.DTA_KNOWLEDGE_STORAGE,\n workspace?.mounts.knowledge || '',\n existsSync(join(cwd, 'knowledge', 'INDEX.md')) ? 'local-md:knowledge/INDEX.md' : '',\n )\n const skills = select(\n options.skills, options.context?.skills, process.env.DTA_SKILLS_SOURCE,\n workspace?.mounts.skills || '', existsSync(join(cwd, 'skills')) ? 'local-dir:skills' : '',\n )\n const state = select(\n options.stateDir, options.context?.stateDir, process.env.DTA_STATE_DIR,\n '', '.dingtalk-agent',\n )\n const artifacts = select(\n options.artifacts, options.context?.artifacts, process.env.DTA_ARTIFACTS_STORAGE,\n '', `local-dir:${resolve(cwd, state.value, 'artifacts')}`,\n )\n const dwsProfile = select(\n options.profile, options.context?.profile, process.env.DTA_DWS_PROFILE,\n workspace?.dws.profile || '', '',\n )\n const expectedUserId = select(\n options.expectedUserId, options.context?.expectedUserId, process.env.DTA_EXPECTED_USER_ID,\n workspace?.dws.expectedUserId || '', '',\n )\n const storage = agent.value\n const stateDir = resolve(cwd, state.value)\n let mounts = workspace && agent.value === 'workspace-manifest'\n ? hydrateWorkspace(cwd, workspace, stateDir, dwsProfile.value, options.deferRemote)\n : hydrateStorage(cwd, agent.value, stateDir, dwsProfile.value, 'body', options.deferRemote)\n mounts = mergeMounts(mounts, hydrateOptional(\n cwd, memory.value, stateDir, dwsProfile.value, 'memory', options.deferRemote))\n mounts = mergeMounts(mounts, hydrateOptional(\n cwd, knowledge.value, stateDir, dwsProfile.value, 'knowledge', options.deferRemote))\n mounts = mergeMounts(mounts, hydrateOptional(\n cwd, skills.value, stateDir, dwsProfile.value, 'skills', options.deferRemote))\n const contextId = workspace?.contextId || ''\n const scopeSeed = agent.value === 'workspace-manifest' && contextId\n ? contextId : canonicalStorageSeed(storage, cwd)\n const sourcePath = storage.startsWith('local-dir:')\n ? safeLocalPath(cwd, parseStorage(storage).ref, true) : ''\n const origins = {\n agent: agent.origin, memory: memory.origin, knowledge: knowledge.origin,\n skills: skills.origin, artifacts: artifacts.origin, state: state.origin,\n dwsProfile: dwsProfile.origin, expectedUserId: expectedUserId.origin,\n }\n const definition = buildBootstrapDefinition(mounts, {\n source: storage,\n sourcePath,\n memory: memory.value,\n knowledge: knowledge.value,\n artifacts: artifacts.value,\n state: stateDir,\n dwsProfile: dwsProfile.value,\n expectedUserId: expectedUserId.value,\n origins,\n }, agent.value === 'workspace-manifest' ? workspace : null)\n return {\n $schema: 'dingtalk-agent/bootstrap@1',\n mode: workspace ? 'workspace' : 'direct',\n initialized: hasWorkspace,\n scopeId: `scope_${digest(scopeSeed).slice(0, 20)}`,\n contextId,\n storage,\n stateDir: mounts.some((item) => item.provider === 'dingtalk-doc') ? stateDir : '',\n mounts,\n definition,\n invocation: directInvocation(),\n note: hasWorkspace\n ? '已读取现有 Workspace;init 不是每次 Session 的前置动作。'\n : '未初始化 Workspace;已按直接会话模式工作,不会自动修改当前目录。',\n }\n}\n\nfunction hydrateWorkspace(\n root: string,\n workspace: WorkspaceSpec,\n stateDir: string,\n profile = '',\n deferRemote = false,\n): BootstrapMount[] {\n const out: BootstrapMount[] = []\n for (const slot of ['profile', 'memory', 'knowledge'] as const) {\n out.push(...hydrateStorage(\n root,\n workspace.mounts[slot],\n stateDir,\n profile || workspace.dws.profile,\n slot,\n deferRemote,\n ))\n }\n return out\n}\n\nfunction hydrateStorage(\n root: string,\n uri: string,\n stateDir: string,\n profile = '',\n slot = 'workspace',\n deferRemote = false,\n): BootstrapMount[] {\n const mount = parseStorage(uri)\n if (mount.provider === 'local-dir') {\n if (slot === 'skills') {\n return discoverSkillDirectory(root, mount.ref)\n }\n const discovered = discoverLocalDirectory(root, mount.ref)\n return slot === 'body' || slot === 'workspace'\n ? discovered\n : discovered.filter((item) => item.slot === slot)\n }\n if (mount.provider === 'local-md') {\n const path = safeLocalPath(root, mount.ref, false)\n if (!path) return []\n const markdown = readFileSync(path, 'utf8')\n const effectiveSlot = slot === 'skills'\n ? `skill:${readSkillName(markdown) || safeName(path)}` : slot\n return [{ slot: effectiveSlot, provider: mount.provider, source: uri, path, hash: digest(markdown) }]\n }\n\n if (deferRemote) return []\n\n // /i/nodes URL 是多产品统一入口;先 probe,只有在线文档 adoc 才能作为 Markdown Storage。\n const info = dws.docInfo(mount.ref, profile)\n const contentType = String(info?.contentType || '').toUpperCase()\n const extension = String(info?.extension || '').toLowerCase()\n if (contentType !== 'ALIDOC' || extension !== 'adoc') {\n throw new Error(\n `dingtalk-doc 只接受在线文档 adoc;实际 contentType=${contentType || '?'} extension=${extension || '?'}`,\n )\n }\n const markdown = String(dws.readDoc(mount.ref, profile))\n const scope = digest(uri).slice(0, 20)\n const effectiveSlot = slot === 'skills'\n ? `skill:${readSkillName(markdown) || safeName(mount.ref)}` : slot\n // A single remote document may intentionally back more than one semantic slot.\n // Give each slot its own directory so its manifest cannot overwrite another slot.\n const path = join(\n stateDir, 'cache', 'bootstrap', scope, safeName(effectiveSlot), 'snapshot.md')\n // Cache bytes must be identical to the independently read remote bytes. Adding\n // formatting here would make the manifest hash describe data that is not on disk.\n writeAtomic(path, markdown)\n const manifest = join(dirname(path), 'manifest.json')\n writeAtomic(manifest, JSON.stringify({\n $schema: 'dingtalk-agent/bootstrap-cache@1',\n source: uri,\n profile,\n pulledAt: new Date().toISOString(),\n hash: digest(markdown),\n path,\n }, null, 2) + '\\n')\n return [{ slot: effectiveSlot, provider: mount.provider, source: uri, path, hash: digest(markdown) }]\n}\n\nfunction discoverLocalDirectory(root: string, ref: string): BootstrapMount[] {\n const directory = safeLocalPath(root, ref, true)\n if (!directory || !lstatSync(directory).isDirectory()) {\n throw new Error(`local-dir 不是目录: ${ref}`)\n }\n const candidates: Array<[string, string]> = [\n ['body', 'AGENTS.md'],\n ['profile', 'WORKSPACE.md'],\n ['memory', 'MEMORY.md'],\n ['knowledge', join('knowledge', 'INDEX.md')],\n ]\n const out: BootstrapMount[] = []\n for (const [slot, rel] of candidates) {\n const path = resolve(directory, rel)\n if (!existsSync(path) || !lstatSync(path).isFile()) continue\n const markdown = readFileSync(path, 'utf8')\n out.push({\n slot,\n provider: 'local-dir',\n source: `local-dir:${directory}`,\n path,\n hash: digest(markdown),\n })\n }\n out.push(...discoverSkillDirectory(root, join(directory, 'skills'), true))\n return out\n}\n\nfunction discoverSkillDirectory(root: string, ref: string, optional = false): BootstrapMount[] {\n const candidate = resolve(root, ref)\n if (!existsSync(candidate)) {\n if (optional) return []\n throw new Error(`Skill Storage 不存在: ${ref}`)\n }\n const directory = realpathSync(candidate)\n if (!lstatSync(directory).isDirectory()) throw new Error(`Skill Storage 不是目录: ${ref}`)\n const roots = existsSync(join(directory, 'SKILL.md'))\n ? [directory]\n : readdirSync(directory).sort().map((name) => join(directory, name))\n .filter((path) => existsSync(join(path, 'SKILL.md')) && lstatSync(path).isDirectory())\n return roots.map((path) => {\n const markdown = readFileSync(join(path, 'SKILL.md'), 'utf8')\n const name = readSkillName(markdown) || basename(path)\n return {\n slot: `skill:${name}`, provider: 'local-dir' as const,\n source: `local-dir:${directory}`, path: join(path, 'SKILL.md'), hash: digest(markdown),\n }\n })\n}\n\nfunction hydrateOptional(\n root: string, uri: string, stateDir: string, profile: string, slot: string,\n deferRemote = false,\n): BootstrapMount[] {\n return uri ? hydrateStorage(root, uri, stateDir, profile, slot, deferRemote) : []\n}\n\nfunction mergeMounts(current: BootstrapMount[], additions: BootstrapMount[]): BootstrapMount[] {\n const out = [...current]\n for (const addition of additions) {\n const index = out.findIndex((item) => item.slot === addition.slot)\n if (index >= 0) out[index] = addition\n else out.push(addition)\n }\n return out\n}\n\nfunction readSkillName(markdown: string): string {\n const frontmatter = markdown.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---/)\n return frontmatter?.[1].match(/^name:\\s*['\"]?([^'\"\\r\\n]+)['\"]?\\s*$/m)?.[1]?.trim() || ''\n}\n\ntype ConfigOrigin = AgentDefinition['configuration'][string]\n\nfunction select(\n explicit: unknown, context: unknown, environment: unknown,\n workspace: unknown, convention: string,\n): { value: string; origin: ConfigOrigin } {\n const choices: Array<[unknown, ConfigOrigin]> = [\n [explicit, 'explicit'], [context, 'context'], [environment, 'environment'],\n [workspace, 'workspace'], [convention, 'convention'],\n ]\n for (const [value, origin] of choices) {\n if (typeof value === 'string' && value.trim()) return { value: value.trim(), origin }\n }\n return { value: '', origin: 'convention' }\n}\n\nfunction parseStorage(uri: string): { provider: Provider; ref: string } {\n const separator = uri.indexOf(':')\n const provider = separator < 0 ? '' : uri.slice(0, separator)\n const ref = separator < 0 ? '' : uri.slice(separator + 1).trim()\n if (!['local-dir', 'local-md', 'dingtalk-doc'].includes(provider) || !ref) {\n throw new Error(\n `Storage URI 不合法: ${uri};使用 local-dir:<path> / local-md:<path> / dingtalk-doc:<node-or-url>`,\n )\n }\n return { provider: provider as Provider, ref }\n}\n\nfunction safeLocalPath(root: string, ref: string, allowAbsolute: boolean): string {\n const rootReal = realpathSync(resolve(root))\n const candidate = resolve(rootReal, ref)\n if (!existsSync(candidate)) {\n if (!allowAbsolute) return ''\n throw new Error(`Storage 不存在: ${ref}`)\n }\n const actual = realpathSync(candidate)\n if (!allowAbsolute) {\n const rel = relative(rootReal, actual)\n if (rel === '..' || rel.startsWith(`..${process.platform === 'win32' ? '\\\\' : '/'}`)) {\n throw new Error(`local-md 必须位于当前 Workspace 内: ${ref}`)\n }\n }\n return actual\n}\n\nfunction canonicalStorageSeed(storage: string, root: string): string {\n const mount = parseStorage(storage)\n return mount.provider === 'local-dir'\n ? `local-dir:${realpathSync(resolve(root, mount.ref))}`\n : storage\n}\n\nfunction writeAtomic(path: string, value: string): void {\n mkdirSync(dirname(path), { recursive: true })\n const temp = `${path}.${process.pid}.${Date.now()}.tmp`\n writeFileSync(temp, value, { flag: 'wx' })\n renameSync(temp, path)\n}\n\nfunction safeName(value: string): string {\n return basename(value).replace(/[^a-zA-Z0-9._-]+/g, '-') || 'workspace'\n}\n"]}
|
|
1
|
+
{"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/bootstrap.ts"],"names":[],"mappings":"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","sourcesContent":["// Agent Session 的轻量水合入口。\n//\n// 它不要求 init,也不创建项目模板:\n// - local-dir 直接返回可读的 Markdown 挂载;\n// - dingtalk-doc 通过 DWS 拉成隐藏的只读快照;\n// - 已有 workspace@1 时复用其中的 mounts。\n\nimport {\n existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, realpathSync, renameSync,\n writeFileSync,\n} from 'node:fs'\nimport { basename, dirname, join, relative, resolve } from 'node:path'\nimport { digest } from './events.js'\nimport * as dws from './dws.js'\nimport { buildBootstrapDefinition } from './agent-definition.js'\nimport { directInvocation } from './invocation.js'\nimport type { AgentDefinition, InvocationContext } from './types.js'\nimport { loadWorkspace, workspacePath, type WorkspaceSpec } from './workspace.js'\n\ntype Provider = 'local-dir' | 'local-md' | 'dingtalk-doc'\n\nexport interface BootstrapOptions {\n agent?: string\n storage?: string\n memory?: string\n knowledge?: string\n skills?: string\n artifacts?: string\n stateDir?: string\n profile?: string\n expectedUserId?: string\n /** Inspect bindings without reading a remote provider. Used by the local agent audit. */\n deferRemote?: boolean\n context?: Partial<{\n agent: string\n memory: string\n knowledge: string\n skills: string\n artifacts: string\n stateDir: string\n profile: string\n expectedUserId: string\n }>\n}\n\nexport interface BootstrapMount {\n slot: string\n provider: Provider\n source: string\n path: string\n hash: string\n}\n\nexport interface BootstrapResult {\n $schema: 'dingtalk-agent/bootstrap@1'\n mode: 'direct' | 'workspace'\n initialized: boolean\n scopeId: string\n contextId: string\n storage: string\n stateDir: string\n mounts: BootstrapMount[]\n definition: AgentDefinition\n invocation: InvocationContext\n note: string\n}\n\nexport function bootstrap(root: string, options: BootstrapOptions = {}): BootstrapResult {\n // Canonicalize aliases such as macOS /var -> /private/var so bootstrap,\n // agent audit, evidence fingerprints, and later Session snapshots hash the\n // same Agent root.\n const cwd = realpathSync(resolve(root))\n const hasWorkspace = existsSync(workspacePath(cwd))\n const workspace = hasWorkspace ? loadWorkspace(cwd) : null\n const packagedAgentRoot = existsSync(join(cwd, 'agent', 'AGENTS.md'))\n ? join(cwd, 'agent') : cwd\n const packagedSkillsRef = existsSync(join(cwd, 'agent', 'skills'))\n ? 'agent/skills' : existsSync(join(cwd, 'skills')) ? 'skills' : ''\n const agent = select(\n options.agent || options.storage, options.context?.agent, process.env.DTA_AGENT_SOURCE,\n workspace ? 'workspace-manifest' : '', `local-dir:${packagedAgentRoot}`,\n )\n const memory = select(\n options.memory, options.context?.memory, process.env.DTA_MEMORY_STORAGE,\n workspace?.mounts.memory || '', existsSync(join(cwd, 'MEMORY.md')) ? 'local-md:MEMORY.md' : '',\n )\n const knowledge = select(\n options.knowledge, options.context?.knowledge, process.env.DTA_KNOWLEDGE_STORAGE,\n workspace?.mounts.knowledge || '',\n existsSync(join(cwd, 'knowledge', 'INDEX.md')) ? 'local-md:knowledge/INDEX.md' : '',\n )\n const skills = select(\n options.skills, options.context?.skills, process.env.DTA_SKILLS_SOURCE,\n workspace?.mounts.skills || '', packagedSkillsRef ? `local-dir:${packagedSkillsRef}` : '',\n )\n const state = select(\n options.stateDir, options.context?.stateDir, process.env.DTA_STATE_DIR,\n '', '.dingtalk-agent',\n )\n const artifacts = select(\n options.artifacts, options.context?.artifacts, process.env.DTA_ARTIFACTS_STORAGE,\n '', `local-dir:${resolve(cwd, state.value, 'artifacts')}`,\n )\n const dwsProfile = select(\n options.profile, options.context?.profile, process.env.DTA_DWS_PROFILE,\n workspace?.dws.profile || '', '',\n )\n const expectedUserId = select(\n options.expectedUserId, options.context?.expectedUserId, process.env.DTA_EXPECTED_USER_ID,\n workspace?.dws.expectedUserId || '', '',\n )\n const storage = agent.value\n const stateDir = resolve(cwd, state.value)\n let mounts = workspace && agent.value === 'workspace-manifest'\n ? hydrateWorkspace(cwd, workspace, stateDir, dwsProfile.value, options.deferRemote)\n : hydrateStorage(cwd, agent.value, stateDir, dwsProfile.value, 'body', options.deferRemote)\n mounts = mergeMounts(mounts, hydrateOptional(\n cwd, memory.value, stateDir, dwsProfile.value, 'memory', options.deferRemote))\n mounts = mergeMounts(mounts, hydrateOptional(\n cwd, knowledge.value, stateDir, dwsProfile.value, 'knowledge', options.deferRemote))\n mounts = mergeMounts(mounts, hydrateOptional(\n cwd, skills.value, stateDir, dwsProfile.value, 'skills', options.deferRemote))\n const contextId = workspace?.contextId || ''\n const scopeSeed = agent.value === 'workspace-manifest' && contextId\n ? contextId : canonicalStorageSeed(storage, cwd)\n const sourcePath = storage.startsWith('local-dir:')\n ? safeLocalPath(cwd, parseStorage(storage).ref, true) : ''\n const origins = {\n agent: agent.origin, memory: memory.origin, knowledge: knowledge.origin,\n skills: skills.origin, artifacts: artifacts.origin, state: state.origin,\n dwsProfile: dwsProfile.origin, expectedUserId: expectedUserId.origin,\n }\n const definition = buildBootstrapDefinition(mounts, {\n source: storage,\n sourcePath,\n memory: memory.value,\n knowledge: knowledge.value,\n artifacts: artifacts.value,\n state: stateDir,\n dwsProfile: dwsProfile.value,\n expectedUserId: expectedUserId.value,\n origins,\n }, agent.value === 'workspace-manifest' ? workspace : null)\n return {\n $schema: 'dingtalk-agent/bootstrap@1',\n mode: workspace ? 'workspace' : 'direct',\n initialized: hasWorkspace,\n scopeId: `scope_${digest(scopeSeed).slice(0, 20)}`,\n contextId,\n storage,\n stateDir: mounts.some((item) => item.provider === 'dingtalk-doc') ? stateDir : '',\n mounts,\n definition,\n invocation: directInvocation(),\n note: hasWorkspace\n ? '已读取现有 Workspace;init 不是每次 Session 的前置动作。'\n : '未初始化 Workspace;已按直接会话模式工作,不会自动修改当前目录。',\n }\n}\n\nfunction hydrateWorkspace(\n root: string,\n workspace: WorkspaceSpec,\n stateDir: string,\n profile = '',\n deferRemote = false,\n): BootstrapMount[] {\n const out: BootstrapMount[] = []\n for (const slot of ['profile', 'memory', 'knowledge'] as const) {\n out.push(...hydrateStorage(\n root,\n workspace.mounts[slot],\n stateDir,\n profile || workspace.dws.profile,\n slot,\n deferRemote,\n ))\n }\n return out\n}\n\nfunction hydrateStorage(\n root: string,\n uri: string,\n stateDir: string,\n profile = '',\n slot = 'workspace',\n deferRemote = false,\n): BootstrapMount[] {\n const mount = parseStorage(uri)\n if (mount.provider === 'local-dir') {\n if (slot === 'skills') {\n return discoverSkillDirectory(root, mount.ref)\n }\n const discovered = discoverLocalDirectory(root, mount.ref)\n return slot === 'body' || slot === 'workspace'\n ? discovered\n : discovered.filter((item) => item.slot === slot)\n }\n if (mount.provider === 'local-md') {\n const path = safeLocalPath(root, mount.ref, false)\n if (!path) return []\n const markdown = readFileSync(path, 'utf8')\n const effectiveSlot = slot === 'skills'\n ? `skill:${readSkillName(markdown) || safeName(path)}` : slot\n return [{ slot: effectiveSlot, provider: mount.provider, source: uri, path, hash: digest(markdown) }]\n }\n\n if (deferRemote) return []\n\n // /i/nodes URL 是多产品统一入口;先 probe,只有在线文档 adoc 才能作为 Markdown Storage。\n const info = dws.docInfo(mount.ref, profile)\n const contentType = String(info?.contentType || '').toUpperCase()\n const extension = String(info?.extension || '').toLowerCase()\n if (contentType !== 'ALIDOC' || extension !== 'adoc') {\n throw new Error(\n `dingtalk-doc 只接受在线文档 adoc;实际 contentType=${contentType || '?'} extension=${extension || '?'}`,\n )\n }\n const markdown = String(dws.readDoc(mount.ref, profile))\n const scope = digest(uri).slice(0, 20)\n const effectiveSlot = slot === 'skills'\n ? `skill:${readSkillName(markdown) || safeName(mount.ref)}` : slot\n // A single remote document may intentionally back more than one semantic slot.\n // Give each slot its own directory so its manifest cannot overwrite another slot.\n const path = join(\n stateDir, 'cache', 'bootstrap', scope, safeName(effectiveSlot), 'snapshot.md')\n // Cache bytes must be identical to the independently read remote bytes. Adding\n // formatting here would make the manifest hash describe data that is not on disk.\n writeAtomic(path, markdown)\n const manifest = join(dirname(path), 'manifest.json')\n writeAtomic(manifest, JSON.stringify({\n $schema: 'dingtalk-agent/bootstrap-cache@1',\n source: uri,\n profile,\n pulledAt: new Date().toISOString(),\n hash: digest(markdown),\n path,\n }, null, 2) + '\\n')\n return [{ slot: effectiveSlot, provider: mount.provider, source: uri, path, hash: digest(markdown) }]\n}\n\nfunction discoverLocalDirectory(root: string, ref: string): BootstrapMount[] {\n const directory = safeLocalPath(root, ref, true)\n if (!directory || !lstatSync(directory).isDirectory()) {\n throw new Error(`local-dir 不是目录: ${ref}`)\n }\n const candidates: Array<[string, string]> = [\n ['body', 'AGENTS.md'],\n ['profile', 'WORKSPACE.md'],\n ['memory', 'MEMORY.md'],\n ['knowledge', join('knowledge', 'INDEX.md')],\n ]\n const out: BootstrapMount[] = []\n for (const [slot, rel] of candidates) {\n const path = resolve(directory, rel)\n if (!existsSync(path) || !lstatSync(path).isFile()) continue\n const markdown = readFileSync(path, 'utf8')\n out.push({\n slot,\n provider: 'local-dir',\n source: `local-dir:${directory}`,\n path,\n hash: digest(markdown),\n })\n }\n out.push(...discoverSkillDirectory(root, join(directory, 'skills'), true))\n return out\n}\n\nfunction discoverSkillDirectory(root: string, ref: string, optional = false): BootstrapMount[] {\n const candidate = resolve(root, ref)\n if (!existsSync(candidate)) {\n if (optional) return []\n throw new Error(`Skill Storage 不存在: ${ref}`)\n }\n const directory = realpathSync(candidate)\n if (!lstatSync(directory).isDirectory()) throw new Error(`Skill Storage 不是目录: ${ref}`)\n const roots = existsSync(join(directory, 'SKILL.md'))\n ? [directory]\n : readdirSync(directory).sort().map((name) => join(directory, name))\n .filter((path) => existsSync(join(path, 'SKILL.md')) && lstatSync(path).isDirectory())\n return roots.map((path) => {\n const markdown = readFileSync(join(path, 'SKILL.md'), 'utf8')\n const name = readSkillName(markdown) || basename(path)\n return {\n slot: `skill:${name}`, provider: 'local-dir' as const,\n source: `local-dir:${directory}`, path: join(path, 'SKILL.md'), hash: digest(markdown),\n }\n })\n}\n\nfunction hydrateOptional(\n root: string, uri: string, stateDir: string, profile: string, slot: string,\n deferRemote = false,\n): BootstrapMount[] {\n return uri ? hydrateStorage(root, uri, stateDir, profile, slot, deferRemote) : []\n}\n\nfunction mergeMounts(current: BootstrapMount[], additions: BootstrapMount[]): BootstrapMount[] {\n const out = [...current]\n for (const addition of additions) {\n const index = out.findIndex((item) => item.slot === addition.slot)\n if (index >= 0) out[index] = addition\n else out.push(addition)\n }\n return out\n}\n\nfunction readSkillName(markdown: string): string {\n const frontmatter = markdown.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---/)\n return frontmatter?.[1].match(/^name:\\s*['\"]?([^'\"\\r\\n]+)['\"]?\\s*$/m)?.[1]?.trim() || ''\n}\n\ntype ConfigOrigin = AgentDefinition['configuration'][string]\n\nfunction select(\n explicit: unknown, context: unknown, environment: unknown,\n workspace: unknown, convention: string,\n): { value: string; origin: ConfigOrigin } {\n const choices: Array<[unknown, ConfigOrigin]> = [\n [explicit, 'explicit'], [context, 'context'], [environment, 'environment'],\n [workspace, 'workspace'], [convention, 'convention'],\n ]\n for (const [value, origin] of choices) {\n if (typeof value === 'string' && value.trim()) return { value: value.trim(), origin }\n }\n return { value: '', origin: 'convention' }\n}\n\nfunction parseStorage(uri: string): { provider: Provider; ref: string } {\n const separator = uri.indexOf(':')\n const provider = separator < 0 ? '' : uri.slice(0, separator)\n const ref = separator < 0 ? '' : uri.slice(separator + 1).trim()\n if (!['local-dir', 'local-md', 'dingtalk-doc'].includes(provider) || !ref) {\n throw new Error(\n `Storage URI 不合法: ${uri};使用 local-dir:<path> / local-md:<path> / dingtalk-doc:<node-or-url>`,\n )\n }\n return { provider: provider as Provider, ref }\n}\n\nfunction safeLocalPath(root: string, ref: string, allowAbsolute: boolean): string {\n const rootReal = realpathSync(resolve(root))\n const candidate = resolve(rootReal, ref)\n if (!existsSync(candidate)) {\n if (!allowAbsolute) return ''\n throw new Error(`Storage 不存在: ${ref}`)\n }\n const actual = realpathSync(candidate)\n if (!allowAbsolute) {\n const rel = relative(rootReal, actual)\n if (rel === '..' || rel.startsWith(`..${process.platform === 'win32' ? '\\\\' : '/'}`)) {\n throw new Error(`local-md 必须位于当前 Workspace 内: ${ref}`)\n }\n }\n return actual\n}\n\nfunction canonicalStorageSeed(storage: string, root: string): string {\n const mount = parseStorage(storage)\n return mount.provider === 'local-dir'\n ? `local-dir:${realpathSync(resolve(root, mount.ref))}`\n : storage\n}\n\nfunction writeAtomic(path: string, value: string): void {\n mkdirSync(dirname(path), { recursive: true })\n const temp = `${path}.${process.pid}.${Date.now()}.tmp`\n writeFileSync(temp, value, { flag: 'wx' })\n renameSync(temp, path)\n}\n\nfunction safeName(value: string): string {\n return basename(value).replace(/[^a-zA-Z0-9._-]+/g, '-') || 'workspace'\n}\n"]}
|
|
@@ -5,15 +5,51 @@ import { findExecutable } from './doctor.js';
|
|
|
5
5
|
import { digest, stableStringify } from './events.js';
|
|
6
6
|
import { resolvePackageRoot } from './package-root.js';
|
|
7
7
|
import { loadWorkspace, workspacePath } from './workspace.js';
|
|
8
|
-
import { bundledSkillPath } from './skill-manager.js';
|
|
8
|
+
import { bundledSkillPath, GLOBAL_SKILL_NAME, isBasicSkillName } from './skill-manager.js';
|
|
9
9
|
export const PROJECT_FILE = 'dingtalk-agent.json';
|
|
10
10
|
export const CURRENT_WORKSPACE_FILE = '.dingtalk-agent/current-workspace';
|
|
11
11
|
export const WORKSPACE_STATE_ROOT = '.dingtalk-agent/state/workspaces';
|
|
12
12
|
export const LEGACY_WORKSPACE_NAME = 'legacy-prepared';
|
|
13
|
+
/**
|
|
14
|
+
* Env variables the multica CLI itself interprets as auth/target switches. `MULTICA_AGENT_ID`
|
|
15
|
+
* flips it into agent-identity auth, so a developer token suddenly reads as "Not
|
|
16
|
+
* authenticated" — a 100%-reproducible deadlock when a manifest envRef reuses the name.
|
|
17
|
+
* `MULTICA_SERVER_URL` / `MULTICA_TOKEN` silently redirect endpoint or identity out from
|
|
18
|
+
* under the named profile that dta's deploy contract pins (a stray pre-prod URL in the shell
|
|
19
|
+
* must never retarget a production deploy). dta strips these from provider subprocess env;
|
|
20
|
+
* doctor warns when a manifest ref collides with them.
|
|
21
|
+
*/
|
|
22
|
+
export const RESERVED_MULTICA_ENV = [
|
|
23
|
+
'MULTICA_AGENT_ID', 'MULTICA_SERVER_URL', 'MULTICA_TOKEN',
|
|
24
|
+
];
|
|
25
|
+
/**
|
|
26
|
+
* 部署与 schedule 共用的 Agent ID 来源选择:声明的 `provider.agentIdFrom` 优先——
|
|
27
|
+
* 即使 env 当前为空(「已声明未绑定」意为可创建,不落回 state);完全未声明时才回退
|
|
28
|
+
* 首次 deploy 写进 state 的真实 ID。语义与 deploy 的 resolveMulticaTarget 一字不差;
|
|
29
|
+
* schedule 曾自己手写这段并漏掉 state 回退,导致黄金路径(scaffold 故意省略
|
|
30
|
+
* agentIdFrom)下 schedule 整体不可用。来源选择只此一份,防两处漂移。
|
|
31
|
+
*/
|
|
32
|
+
export function multicaAgentIdSource(workspace) {
|
|
33
|
+
if (workspace.provider.agentIdFrom) {
|
|
34
|
+
return { kind: 'declared', ref: workspace.provider.agentIdFrom };
|
|
35
|
+
}
|
|
36
|
+
const stateAgentId = workspace.state?.binding.agentId || '';
|
|
37
|
+
if (stateAgentId)
|
|
38
|
+
return { kind: 'state', agentId: stateAgentId };
|
|
39
|
+
return { kind: 'none' };
|
|
40
|
+
}
|
|
13
41
|
const PROJECT_KEYS = new Set(['$schema', 'name', 'dtaVersion', 'agent', 'workspaces']);
|
|
14
|
-
const PROJECT_OPTIONAL_KEYS = new Set([
|
|
15
|
-
|
|
42
|
+
const PROJECT_OPTIONAL_KEYS = new Set([
|
|
43
|
+
...PROJECT_KEYS, 'agentPlatform', 'multicaEndpoint', 'predicates', 'schedules',
|
|
44
|
+
]);
|
|
45
|
+
const PREDICATE_KEYS = new Set(['description', 'source']);
|
|
46
|
+
export const PREDICATE_ID = /^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$/;
|
|
47
|
+
const AGENT_KEYS = new Set(['definition', 'skillsRoot', 'displayName', 'skills']);
|
|
16
48
|
const AGENT_REQUIRED_KEYS = new Set(['definition', 'skills']);
|
|
49
|
+
const SCHEDULE_KEYS = new Set(['name', 'cron', 'timezone', 'mode', 'wake', 'purpose',
|
|
50
|
+
'completion', 'unit', 'evidence', 'supervision']);
|
|
51
|
+
const SCHEDULE_REQUIRED_KEYS = new Set(['name', 'cron', 'timezone', 'mode']);
|
|
52
|
+
const SCHEDULE_MODES = new Set(['ephemeral', 'work-item']);
|
|
17
53
|
const WORKSPACE_KEYS = new Set(['stage', 'provider', 'storage', 'authority']);
|
|
18
54
|
const OPENCODE_KEYS = new Set(['kind', 'model']);
|
|
19
55
|
const MULTICA_KEYS = new Set([
|
|
@@ -21,6 +57,10 @@ const MULTICA_KEYS = new Set([
|
|
|
21
57
|
]);
|
|
22
58
|
const STORAGE_KEYS = new Set(['memory', 'knowledge', 'artifacts']);
|
|
23
59
|
const AUTHORITY_KEYS = new Set(['dwsProfileFrom', 'expectedUserIdFrom']);
|
|
60
|
+
export const PROVIDER_CONTRACTS = {
|
|
61
|
+
opencode: { kind: 'opencode', requiresAuthority: false },
|
|
62
|
+
multica: { kind: 'multica', requiresAuthority: true },
|
|
63
|
+
};
|
|
24
64
|
const STATE_KEYS = new Set([
|
|
25
65
|
'$schema', 'workspace', 'provider', 'status', 'binding', 'desiredHash', 'observedHash',
|
|
26
66
|
'lastPlanId', 'lastReceiptId', 'lastEvalId',
|
|
@@ -70,7 +110,10 @@ export function inspectAgentProject(start = process.cwd(), cliVersion = '') {
|
|
|
70
110
|
dtaVersion: loaded.manifest.dtaVersion,
|
|
71
111
|
compatibleWithCli: !cliVersion || versionSatisfies(cliVersion, loaded.manifest.dtaVersion),
|
|
72
112
|
definition: loaded.manifest.agent.definition,
|
|
113
|
+
skillsRoot: loaded.manifest.agent.skillsRoot || '',
|
|
73
114
|
skills: [...loaded.manifest.agent.skills],
|
|
115
|
+
...(loaded.manifest.predicates ? { predicates: { ...loaded.manifest.predicates } } : {}),
|
|
116
|
+
schedules: loaded.manifest.schedules ? [...loaded.manifest.schedules] : [],
|
|
74
117
|
},
|
|
75
118
|
currentWorkspace,
|
|
76
119
|
workspaces: declared,
|
|
@@ -153,7 +196,8 @@ export function doctorDevelopmentWorkspace(start, name, options = {}) {
|
|
|
153
196
|
function loadAgentProject(start) {
|
|
154
197
|
const root = findAgentProjectRoot(start);
|
|
155
198
|
if (!root) {
|
|
156
|
-
throw new Error(`找不到 ${PROJECT_FILE} 或 ${workspacePath('<project>')};请在 Agent Project
|
|
199
|
+
throw new Error(`找不到 ${PROJECT_FILE} 或 ${workspacePath('<project>')};请在 Agent Project 内运行。` +
|
|
200
|
+
'从零开始:先准备 Role Skill,再用 dta agent enhance 生成完整 Agent Project(含 dingtalk-agent.json)');
|
|
157
201
|
}
|
|
158
202
|
const manifestPath = join(root, PROJECT_FILE);
|
|
159
203
|
const legacyPath = workspacePath(root);
|
|
@@ -189,6 +233,72 @@ function loadAgentProject(start) {
|
|
|
189
233
|
manifestHash: digest(stableStringify(manifest)), legacy,
|
|
190
234
|
};
|
|
191
235
|
}
|
|
236
|
+
function validateCron(expr, label) {
|
|
237
|
+
const value = requiredString(expr, label);
|
|
238
|
+
if (value.startsWith('@')) {
|
|
239
|
+
throw new Error(`${label} 不支持 @macro(如 @daily);用标准 5 段 cron`);
|
|
240
|
+
}
|
|
241
|
+
const fields = value.trim().split(/\s+/);
|
|
242
|
+
if (fields.length !== 5) {
|
|
243
|
+
throw new Error(`${label} 必须是标准 5 段 cron(分 时 日 月 周);得到 ${fields.length} 段: "${value}"`);
|
|
244
|
+
}
|
|
245
|
+
return value;
|
|
246
|
+
}
|
|
247
|
+
// 返回 undefined = manifest 根本没写 predicates;返回 {}(含空对象)= 已声明注册表。
|
|
248
|
+
// 这两个状态必须可区分:显式空注册表意味着「本项目已进入引用模式」,自由文本
|
|
249
|
+
// completion 要阻断(issue #39 的 fail-open 正是把空注册表折成了未声明)。
|
|
250
|
+
function validatePredicates(value) {
|
|
251
|
+
if (value === undefined)
|
|
252
|
+
return undefined;
|
|
253
|
+
const input = objectValue(value, 'predicates');
|
|
254
|
+
const out = {};
|
|
255
|
+
for (const [id, raw] of Object.entries(input)) {
|
|
256
|
+
if (!PREDICATE_ID.test(id)) {
|
|
257
|
+
throw new Error(`predicates 的 id 必须是 kebab-case([a-z0-9-],首尾字母数字): "${id}"`);
|
|
258
|
+
}
|
|
259
|
+
const entry = objectValue(raw, `predicates.${id}`);
|
|
260
|
+
assertAllowedKeys(entry, PREDICATE_KEYS, `predicates.${id}`);
|
|
261
|
+
const description = requiredString(entry.description, `predicates.${id}.description`);
|
|
262
|
+
const source = entry.source === undefined
|
|
263
|
+
? undefined : requiredString(entry.source, `predicates.${id}.source`);
|
|
264
|
+
out[id] = { description, ...(source === undefined ? {} : { source }) };
|
|
265
|
+
}
|
|
266
|
+
return out;
|
|
267
|
+
}
|
|
268
|
+
function validateSchedules(value) {
|
|
269
|
+
if (value === undefined)
|
|
270
|
+
return [];
|
|
271
|
+
if (!Array.isArray(value))
|
|
272
|
+
throw new Error('schedules 必须是数组');
|
|
273
|
+
const seen = new Set();
|
|
274
|
+
return value.map((raw, index) => {
|
|
275
|
+
const input = objectValue(raw, `schedules[${index}]`);
|
|
276
|
+
assertAllowedKeys(input, SCHEDULE_KEYS, `schedules[${index}]`);
|
|
277
|
+
const missing = [...SCHEDULE_REQUIRED_KEYS].filter((key) => !(key in input));
|
|
278
|
+
if (missing.length)
|
|
279
|
+
throw new Error(`schedules[${index}] 缺少字段: ${missing.join(', ')}`);
|
|
280
|
+
const name = agentDisplayName(input.name, `schedules[${index}].name`);
|
|
281
|
+
if (seen.has(name))
|
|
282
|
+
throw new Error(`schedules 里的 name 不能重复: ${name}`);
|
|
283
|
+
seen.add(name);
|
|
284
|
+
const cron = validateCron(input.cron, `schedules[${index}].cron`);
|
|
285
|
+
const timezone = requiredString(input.timezone, `schedules[${index}].timezone`);
|
|
286
|
+
const mode = requiredString(input.mode, `schedules[${index}].mode`);
|
|
287
|
+
if (!SCHEDULE_MODES.has(mode)) {
|
|
288
|
+
throw new Error(`schedules[${index}].mode 只能是 ${[...SCHEDULE_MODES].join(' | ')};得到 "${mode}"`);
|
|
289
|
+
}
|
|
290
|
+
const opt = (key) => input[key] === undefined ? undefined : requiredString(input[key], `schedules[${index}].${key}`);
|
|
291
|
+
return {
|
|
292
|
+
name, cron, timezone, mode: mode,
|
|
293
|
+
...(opt('wake') === undefined ? {} : { wake: opt('wake') }),
|
|
294
|
+
...(opt('purpose') === undefined ? {} : { purpose: opt('purpose') }),
|
|
295
|
+
...(opt('completion') === undefined ? {} : { completion: opt('completion') }),
|
|
296
|
+
...(opt('unit') === undefined ? {} : { unit: opt('unit') }),
|
|
297
|
+
...(opt('evidence') === undefined ? {} : { evidence: opt('evidence') }),
|
|
298
|
+
...(opt('supervision') === undefined ? {} : { supervision: opt('supervision') }),
|
|
299
|
+
};
|
|
300
|
+
});
|
|
301
|
+
}
|
|
192
302
|
function validateProjectManifest(value, root) {
|
|
193
303
|
const input = objectValue(value, 'Project manifest');
|
|
194
304
|
assertAllowedKeys(input, PROJECT_OPTIONAL_KEYS, 'Project manifest');
|
|
@@ -210,6 +320,9 @@ function validateProjectManifest(value, root) {
|
|
|
210
320
|
if (missingAgent.length)
|
|
211
321
|
throw new Error(`Project agent 缺少字段: ${missingAgent.join(', ')}`);
|
|
212
322
|
const definition = safeRelativePath(root, requiredString(agentInput.definition, 'agent.definition'), 'agent.definition', false);
|
|
323
|
+
const skillsRoot = agentInput.skillsRoot === undefined
|
|
324
|
+
? undefined
|
|
325
|
+
: safeRelativePath(root, requiredString(agentInput.skillsRoot, 'agent.skillsRoot'), 'agent.skillsRoot', false);
|
|
213
326
|
const displayName = agentInput.displayName === undefined
|
|
214
327
|
? undefined : agentDisplayName(agentInput.displayName, 'agent.displayName');
|
|
215
328
|
if (!Array.isArray(agentInput.skills) || agentInput.skills.length === 0) {
|
|
@@ -218,8 +331,10 @@ function validateProjectManifest(value, root) {
|
|
|
218
331
|
const skills = agentInput.skills.map((item, index) => stableName(item, `agent.skills[${index}]`));
|
|
219
332
|
if (new Set(skills).size !== skills.length)
|
|
220
333
|
throw new Error('agent.skills 不能包含重复项');
|
|
221
|
-
|
|
222
|
-
|
|
334
|
+
// 改名过渡期:旧 Basic 名仍算「显式包含 Basic」,但**不做归一化**——用户仓库里
|
|
335
|
+
// check-in 的目录还叫旧名,改写声明会让 projectSkillRef 解析到不存在的路径。
|
|
336
|
+
if (!skills.some(isBasicSkillName)) {
|
|
337
|
+
throw new Error(`agent.skills 必须显式包含 ${GLOBAL_SKILL_NAME}`);
|
|
223
338
|
}
|
|
224
339
|
const workspaceInput = objectValue(input.workspaces, 'Project workspaces');
|
|
225
340
|
const workspaces = {};
|
|
@@ -230,17 +345,49 @@ function validateProjectManifest(value, root) {
|
|
|
230
345
|
}
|
|
231
346
|
workspaces[workspaceName] = validateDeclaredWorkspace(rawWorkspace, root, workspaceName);
|
|
232
347
|
}
|
|
348
|
+
const schedules = validateSchedules(input.schedules);
|
|
349
|
+
const predicates = validatePredicates(input.predicates);
|
|
233
350
|
return {
|
|
234
351
|
$schema: 'dingtalk-agent/project@1', name, dtaVersion,
|
|
235
352
|
...(agentPlatform === undefined ? {} : { agentPlatform }),
|
|
236
353
|
...(multicaEndpoint === undefined ? {} : { multicaEndpoint }),
|
|
237
|
-
agent: {
|
|
354
|
+
agent: {
|
|
355
|
+
definition,
|
|
356
|
+
...(skillsRoot === undefined ? {} : { skillsRoot }),
|
|
357
|
+
...(displayName === undefined ? {} : { displayName }),
|
|
358
|
+
skills,
|
|
359
|
+
},
|
|
360
|
+
...(predicates !== undefined ? { predicates } : {}),
|
|
361
|
+
...(schedules.length ? { schedules } : {}),
|
|
362
|
+
workspaces,
|
|
238
363
|
};
|
|
239
364
|
}
|
|
365
|
+
/**
|
|
366
|
+
* Resolve the versioned source of a declared Skill.
|
|
367
|
+
*
|
|
368
|
+
* New projects declare one package root (normally agent/skills). Manifests
|
|
369
|
+
* created before skillsRoot keep their historical split layout so an existing
|
|
370
|
+
* code repository can migrate deliberately instead of being rewritten merely
|
|
371
|
+
* because dta was upgraded.
|
|
372
|
+
*/
|
|
373
|
+
export function projectSkillRef(project, name) {
|
|
374
|
+
if (project.skillsRoot)
|
|
375
|
+
return `${project.skillsRoot}/${name}`;
|
|
376
|
+
return isBasicSkillName(name)
|
|
377
|
+
? `.agents/skills/${name}`
|
|
378
|
+
: `skills/${name}`;
|
|
379
|
+
}
|
|
380
|
+
function manifestSkillRef(manifest, name) {
|
|
381
|
+
if (manifest.agent.skillsRoot)
|
|
382
|
+
return `${manifest.agent.skillsRoot}/${name}`;
|
|
383
|
+
return isBasicSkillName(name)
|
|
384
|
+
? `.agents/skills/${name}`
|
|
385
|
+
: `skills/${name}`;
|
|
386
|
+
}
|
|
240
387
|
function validateDeclaredWorkspace(value, root, name) {
|
|
241
388
|
const input = objectValue(value, `Workspace ${name}`);
|
|
242
389
|
assertAllowedKeys(input, WORKSPACE_KEYS, `Workspace ${name}`);
|
|
243
|
-
for (const required of ['stage', 'provider'
|
|
390
|
+
for (const required of ['stage', 'provider']) {
|
|
244
391
|
if (!(required in input))
|
|
245
392
|
throw new Error(`Workspace ${name} 缺少字段: ${required}`);
|
|
246
393
|
}
|
|
@@ -275,10 +422,20 @@ function validateDeclaredWorkspace(value, root, name) {
|
|
|
275
422
|
else {
|
|
276
423
|
throw new Error(`Workspace ${name}.provider.kind 只支持 opencode / multica`);
|
|
277
424
|
}
|
|
278
|
-
const storageInput =
|
|
425
|
+
const storageInput = input.storage === undefined
|
|
426
|
+
? {} : objectValue(input.storage, `Workspace ${name}.storage`);
|
|
279
427
|
assertAllowedKeys(storageInput, STORAGE_KEYS, `Workspace ${name}.storage`);
|
|
280
|
-
|
|
281
|
-
|
|
428
|
+
if (provider.kind === 'opencode') {
|
|
429
|
+
for (const required of ['memory', 'knowledge']) {
|
|
430
|
+
if (!(required in storageInput)) {
|
|
431
|
+
throw new Error(`Workspace ${name}.storage 缺少字段: ${required}`);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
const memory = storageInput.memory === undefined ? undefined
|
|
436
|
+
: storageRoute(storageInput.memory, ['local-md', 'dingtalk-doc'], `${name}.memory`, root);
|
|
437
|
+
const knowledge = storageInput.knowledge === undefined ? undefined
|
|
438
|
+
: storageRoute(storageInput.knowledge, ['local-md', 'dingtalk-doc'], `${name}.knowledge`, root);
|
|
282
439
|
const artifacts = storageInput.artifacts === undefined ? undefined
|
|
283
440
|
: storageRoute(storageInput.artifacts, ['local-dir'], `${name}.artifacts`, root);
|
|
284
441
|
let authority;
|
|
@@ -290,16 +447,30 @@ function validateDeclaredWorkspace(value, root, name) {
|
|
|
290
447
|
expectedUserIdFrom: envReference(authorityInput.expectedUserIdFrom, `${name}.expectedUserIdFrom`),
|
|
291
448
|
};
|
|
292
449
|
}
|
|
293
|
-
if (provider.kind
|
|
294
|
-
throw new Error(`Workspace ${name} 的
|
|
295
|
-
|
|
296
|
-
|
|
450
|
+
if (PROVIDER_CONTRACTS[provider.kind]?.requiresAuthority && !authority) {
|
|
451
|
+
throw new Error(`Workspace ${name} 的 ${provider.kind} Provider 必须声明 authority.dwsProfileFrom 与 ` +
|
|
452
|
+
`authority.expectedUserIdFrom(都用 env: 引用,不接受字面量)。\n` +
|
|
453
|
+
`在该 Workspace 下补上,例如:\n` +
|
|
454
|
+
` "authority": {\n` +
|
|
455
|
+
` "dwsProfileFrom": "env:DTA_DWS_PROFILE",\n` +
|
|
456
|
+
` "expectedUserIdFrom": "env:DTA_EXPECTED_USER_ID"\n` +
|
|
457
|
+
` }\n` +
|
|
458
|
+
`或直接用 dta workspace create ${name} --provider ${provider.kind} 生成完整条目。`);
|
|
459
|
+
}
|
|
460
|
+
return { stage, provider, storage: {
|
|
461
|
+
...(memory ? { memory } : {}),
|
|
462
|
+
...(knowledge ? { knowledge } : {}),
|
|
463
|
+
...(artifacts ? { artifacts } : {}),
|
|
464
|
+
},
|
|
297
465
|
...(authority ? { authority } : {}) };
|
|
298
466
|
}
|
|
299
467
|
function declaredView(loaded, name, workspace, currentWorkspace) {
|
|
300
|
-
const artifacts = workspace.storage.artifacts ||
|
|
301
|
-
`local-dir:.dingtalk-agent/artifacts/${name}
|
|
302
|
-
const storage = {
|
|
468
|
+
const artifacts = workspace.storage.artifacts || (workspace.provider.kind === 'opencode'
|
|
469
|
+
? `local-dir:.dingtalk-agent/artifacts/${name}` : undefined);
|
|
470
|
+
const storage = {
|
|
471
|
+
...workspace.storage,
|
|
472
|
+
...(artifacts ? { artifacts } : {}),
|
|
473
|
+
};
|
|
303
474
|
const sourceHash = projectSourceHash(loaded.root, loaded.manifest);
|
|
304
475
|
const desiredHash = digest(stableStringify({
|
|
305
476
|
project: loaded.manifest.name,
|
|
@@ -372,11 +543,8 @@ function projectSourceHash(root, manifest) {
|
|
|
372
543
|
opencode: localContentHash(root, 'opencode.json'),
|
|
373
544
|
};
|
|
374
545
|
for (const name of manifest.agent.skills) {
|
|
375
|
-
const ref = name
|
|
376
|
-
? `.agents/skills/${name}` : `skills/${name}`;
|
|
546
|
+
const ref = manifestSkillRef(manifest, name);
|
|
377
547
|
sources[`skill:${name}`] = localContentHash(root, ref);
|
|
378
|
-
const exposure = `.agents/skills/${name}`;
|
|
379
|
-
sources[`exposure:${name}`] = localContentHash(root, exposure);
|
|
380
548
|
}
|
|
381
549
|
return digest(stableStringify(sources));
|
|
382
550
|
}
|
|
@@ -463,13 +631,16 @@ function inspectOpenCodeWorkspace(info, workspace, env, add) {
|
|
|
463
631
|
const executable = findExecutable('opencode', env);
|
|
464
632
|
add('provider.opencode-cli', 'provider', executable ? 'pass' : 'fail', true, executable ? 'OpenCode CLI 可执行' : 'PATH 找不到 opencode', { executable: executable || '' }, '安装 OpenCode,并确认 opencode --version 可执行');
|
|
465
633
|
add('provider.opencode-model', 'provider', workspace.provider.model ? 'pass' : 'fail', true, workspace.provider.model ? 'OpenCode model 已显式声明' : 'OpenCode model 缺失', { model: workspace.provider.model || '' });
|
|
466
|
-
|
|
634
|
+
// 路径与 permission 键都跟随**声明的**名字:改名过渡期里 manifest 可能仍写旧名,
|
|
635
|
+
// 而磁盘上的目录、opencode.json 的 permission 键也都还是旧名,三者必须一致。
|
|
636
|
+
const declaredBasic = info.project.skills.find(isBasicSkillName) || GLOBAL_SKILL_NAME;
|
|
637
|
+
const basicPath = `${projectSkillRef(info.project, declaredBasic)}/SKILL.md`;
|
|
467
638
|
const basic = inspectLocalFile(info.root, basicPath);
|
|
468
639
|
const canonicalPackageRoot = resolvePackageRoot(import.meta.url);
|
|
469
|
-
const canonicalBasic = inspectLocalFile(canonicalPackageRoot, relative(canonicalPackageRoot, join(bundledSkillPath(canonicalPackageRoot,
|
|
640
|
+
const canonicalBasic = inspectLocalFile(canonicalPackageRoot, relative(canonicalPackageRoot, join(bundledSkillPath(canonicalPackageRoot, GLOBAL_SKILL_NAME), 'SKILL.md')));
|
|
470
641
|
const basicMatched = basic.valid && canonicalBasic.valid && basic.hash === canonicalBasic.hash;
|
|
471
|
-
add('skills.basic-exposure', 'skills', basicMatched ? 'pass' : 'fail', true, basicMatched ? 'Basic Skill
|
|
472
|
-
: 'Basic Skill
|
|
642
|
+
add('skills.basic-exposure', 'skills', basicMatched ? 'pass' : 'fail', true, basicMatched ? 'Agent package 中的 Basic Skill 与当前 canonical source 一致'
|
|
643
|
+
: 'Agent package 的 Basic Skill 缺失、越界或 hash 漂移', { source: basic, canonicalHash: canonicalBasic.hash || '' }, `重新装配 ${basicPath}`);
|
|
473
644
|
const configPath = join(info.root, 'opencode.json');
|
|
474
645
|
const configFile = inspectLocalFile(info.root, 'opencode.json');
|
|
475
646
|
let configError = '';
|
|
@@ -486,7 +657,7 @@ function inspectOpenCodeWorkspace(info, workspace, env, add) {
|
|
|
486
657
|
!Array.isArray(skillPermissions)
|
|
487
658
|
? Object.fromEntries(Object.entries(skillPermissions).map(([key, value]) => [key, String(value)]))
|
|
488
659
|
: {};
|
|
489
|
-
permission = permissions[
|
|
660
|
+
permission = permissions[declaredBasic] || '';
|
|
490
661
|
}
|
|
491
662
|
catch (error) {
|
|
492
663
|
configError = error.message;
|
|
@@ -496,13 +667,11 @@ function inspectOpenCodeWorkspace(info, workspace, env, add) {
|
|
|
496
667
|
configError = configFile.exists ? 'outside-or-not-file' : 'missing';
|
|
497
668
|
const configValid = !configError && instructionCount === 1 && permission === 'allow';
|
|
498
669
|
add('skills.basic-instruction', 'skills', configValid ? 'pass' : 'fail', true, configValid ? 'OpenCode config 强制加载且允许 Basic Skill' : 'OpenCode Basic instruction/permission 合同不完整', { path: 'opencode.json', error: configError, instructionCount, permission }, '运行 compose/bind 流程生成唯一 Basic instruction 与 allow permission');
|
|
499
|
-
for (const name of info.project.skills.filter((item) => item
|
|
500
|
-
const source = inspectLocalFile(info.root,
|
|
501
|
-
const
|
|
502
|
-
|
|
503
|
-
permissions[name]
|
|
504
|
-
add(`skills.role.${name}`, 'skills', matched ? 'pass' : 'fail', true, matched ? `Role Skill ${name} source/exposure hash 与 permission 一致`
|
|
505
|
-
: `Role Skill ${name} source、exposure hash 或 permission 不一致`, { source, exposure, permission: permissions[name] || '' }, `运行 compose/bind 流程物化 ${name}`);
|
|
670
|
+
for (const name of info.project.skills.filter((item) => !isBasicSkillName(item))) {
|
|
671
|
+
const source = inspectLocalFile(info.root, `${projectSkillRef(info.project, name)}/SKILL.md`);
|
|
672
|
+
const matched = source.valid && permissions[name] === 'allow';
|
|
673
|
+
add(`skills.role.${name}`, 'skills', matched ? 'pass' : 'fail', true, matched ? `Role Skill ${name} 单一发布源与 permission 一致`
|
|
674
|
+
: `Role Skill ${name} 发布源缺失或 permission 不一致`, { source, permission: permissions[name] || '' }, `运行 compose/bind 流程装配 ${name}`);
|
|
506
675
|
}
|
|
507
676
|
const managedRef = workspace.state?.binding.managedPath || '';
|
|
508
677
|
if (managedRef) {
|
|
@@ -548,6 +717,13 @@ function inspectDeclaredMulticaWorkspace(workspace, env, add) {
|
|
|
548
717
|
add('authority.agent-id', 'authority', agentRef && agentConfigured ? 'pass' : 'warn', false, agentRef
|
|
549
718
|
? agentConfigured ? 'agent-id 可信来源已解析' : 'agent-id 来源未设置;只允许列候选,不按名称绑定'
|
|
550
719
|
: '未声明 agent-id;W3 只列候选,W4 create 后必须保存稳定 ID', { source: agentRef, configured: agentConfigured }, agentRef ? `设置 ${agentRef}` : '已有 Agent 时声明 provider.agentIdFrom;新 Agent 由 W4 apply 保存 ID');
|
|
720
|
+
const reservedCollisions = [...refs.map(([, ref]) => ref), agentRef]
|
|
721
|
+
.map((ref) => (ref.startsWith('env:') ? ref.slice(4) : ''))
|
|
722
|
+
.filter((variable) => RESERVED_MULTICA_ENV.includes(variable));
|
|
723
|
+
if (reservedCollisions.length) {
|
|
724
|
+
add('authority.env-reserved-collision', 'authority', 'warn', false, `envRef 命中 multica CLI 保留变量: ${[...new Set(reservedCollisions)].join(', ')};` +
|
|
725
|
+
'该变量会把 multica CLI 切到 Agent 身份鉴权(dta 调用 provider 时已自动剔除)', { reserved: [...new Set(reservedCollisions)] }, '把 manifest 里的 env 引用改成 DTA_ 前缀命名,避免与 provider CLI 语义撞车');
|
|
726
|
+
}
|
|
551
727
|
const inspectionId = workspace.state?.binding.inspectionId || '';
|
|
552
728
|
add('provider.remote-inspect', 'provider', 'warn', false, inspectionId
|
|
553
729
|
? '已有脱敏 Multica 只读 inspection;W4 load/smoke 前仍不能 ready'
|