@xdxer/dingtalk-agent 0.1.4-beta.8 → 0.1.4
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 +233 -0
- package/README.en.md +167 -0
- package/README.md +101 -248
- package/dist/bin/dingtalk-agent.js +1255 -25
- package/dist/bin/dingtalk-agent.js.map +1 -1
- package/dist/src/actions.js +98 -14
- package/dist/src/actions.js.map +1 -1
- package/dist/src/agent-audit.js +1385 -0
- package/dist/src/agent-audit.js.map +1 -0
- package/dist/src/agent-bindings.js +132 -0
- package/dist/src/agent-bindings.js.map +1 -0
- package/dist/src/agent-definition.js +182 -0
- package/dist/src/agent-definition.js.map +1 -0
- package/dist/src/agent-enhance.js +711 -0
- package/dist/src/agent-enhance.js.map +1 -0
- package/dist/src/agent-platform.js +299 -0
- package/dist/src/agent-platform.js.map +1 -0
- package/dist/src/bootstrap.js +125 -17
- package/dist/src/bootstrap.js.map +1 -1
- package/dist/src/config.js +1 -7
- package/dist/src/config.js.map +1 -1
- package/dist/src/development-workspace.js +755 -0
- package/dist/src/development-workspace.js.map +1 -0
- package/dist/src/doctor.js +74 -15
- package/dist/src/doctor.js.map +1 -1
- package/dist/src/dws.js +145 -0
- package/dist/src/dws.js.map +1 -1
- package/dist/src/eval-evidence.js +193 -0
- package/dist/src/eval-evidence.js.map +1 -0
- package/dist/src/host-detect.js +146 -0
- package/dist/src/host-detect.js.map +1 -0
- package/dist/src/instruction-path.js +270 -0
- package/dist/src/instruction-path.js.map +1 -0
- package/dist/src/invocation.js +36 -0
- package/dist/src/invocation.js.map +1 -0
- package/dist/src/lab.js +679 -0
- package/dist/src/lab.js.map +1 -0
- package/dist/src/lease.js +100 -0
- package/dist/src/lease.js.map +1 -0
- package/dist/src/map.js +157 -0
- package/dist/src/map.js.map +1 -0
- package/dist/src/memory/candidates.js +451 -0
- package/dist/src/memory/candidates.js.map +1 -0
- package/dist/src/memory/completion-evidence.js +536 -0
- package/dist/src/memory/completion-evidence.js.map +1 -0
- package/dist/src/memory/operational.js +263 -0
- package/dist/src/memory/operational.js.map +1 -0
- package/dist/src/memory/remote-state.js +478 -0
- package/dist/src/memory/remote-state.js.map +1 -0
- package/dist/src/memory/task-checkpoints.js +204 -0
- package/dist/src/memory/task-checkpoints.js.map +1 -0
- package/dist/src/multica-deploy.js +1538 -0
- package/dist/src/multica-deploy.js.map +1 -0
- package/dist/src/multica-provider.js +685 -0
- package/dist/src/multica-provider.js.map +1 -0
- package/dist/src/opencode-evals.js +1547 -0
- package/dist/src/opencode-evals.js.map +1 -0
- package/dist/src/opencode-isolation.js +124 -0
- package/dist/src/opencode-isolation.js.map +1 -0
- package/dist/src/opencode-provider.js +532 -0
- package/dist/src/opencode-provider.js.map +1 -0
- package/dist/src/opencode-workspace.js +208 -0
- package/dist/src/opencode-workspace.js.map +1 -0
- package/dist/src/perception.js +225 -0
- package/dist/src/perception.js.map +1 -0
- package/dist/src/personal-event-evals.js +595 -0
- package/dist/src/personal-event-evals.js.map +1 -0
- package/dist/src/promotion.js +786 -0
- package/dist/src/promotion.js.map +1 -0
- package/dist/src/remote-semantic-state-live-evals.js +888 -0
- package/dist/src/remote-semantic-state-live-evals.js.map +1 -0
- package/dist/src/remote-semantic-state-worker.js +38 -0
- package/dist/src/remote-semantic-state-worker.js.map +1 -0
- package/dist/src/remote-state-evals.js +502 -0
- package/dist/src/remote-state-evals.js.map +1 -0
- package/dist/src/response-gate.js +51 -0
- package/dist/src/response-gate.js.map +1 -0
- package/dist/src/robot-evals.js +771 -0
- package/dist/src/robot-evals.js.map +1 -0
- package/dist/src/sessions.js +66 -105
- package/dist/src/sessions.js.map +1 -1
- package/dist/src/setup.js +6 -5
- package/dist/src/setup.js.map +1 -1
- package/dist/src/skill-manager.js +162 -24
- package/dist/src/skill-manager.js.map +1 -1
- package/dist/src/skills.js +2 -1
- package/dist/src/skills.js.map +1 -1
- package/dist/src/storage-evals.js +26 -0
- package/dist/src/storage-evals.js.map +1 -0
- package/dist/src/types.js.map +1 -1
- package/dist/src/upgrade.js +23 -27
- package/dist/src/upgrade.js.map +1 -1
- package/dist/src/version.js +73 -0
- package/dist/src/version.js.map +1 -0
- package/dist/src/waits.js +5 -1
- package/dist/src/waits.js.map +1 -1
- package/dist/src/workspace.js +28 -3
- package/dist/src/workspace.js.map +1 -1
- package/docs/INSTALLATION.md +50 -3
- package/docs/SECOND-AGENT-ACCEPTANCE.md +62 -0
- package/docs/architecture/agent-memory-topology.png +0 -0
- package/docs/architecture/agent-memory-topology.svg +132 -0
- package/docs/architecture/general-agent-kernel-topology.png +0 -0
- package/docs/architecture/general-agent-kernel-topology.svg +149 -0
- package/docs/architecture/provider-bound-development-workspace.png +0 -0
- package/docs/architecture/provider-bound-development-workspace.svg +141 -0
- package/docs/architecture/task-completion-gate.png +0 -0
- package/docs/architecture/task-completion-gate.svg +191 -0
- package/docs/assets/agent-delivery-lifecycle.svg +103 -0
- package/docs/schemas/agent-audit-load-evidence.schema.json +14 -0
- package/docs/schemas/agent-audit.schema.json +92 -0
- package/docs/schemas/agent-bindings.schema.json +54 -0
- package/docs/schemas/agent-definition.schema.json +78 -0
- package/docs/schemas/agent-enhancement-plan.schema.json +88 -0
- package/docs/schemas/agent-enhancement-receipt.schema.json +37 -0
- package/docs/schemas/agent-platform.schema.json +13 -0
- package/docs/schemas/enriched-invocation.schema.json +46 -0
- package/docs/schemas/eval-candidate-plan.schema.json +28 -0
- package/docs/schemas/eval-candidate-result.schema.json +20 -0
- package/docs/schemas/eval-candidate.schema.json +30 -0
- package/docs/schemas/invocation.schema.json +19 -0
- package/docs/schemas/memory-candidate-proposal.schema.json +18 -0
- package/docs/schemas/memory-candidate.schema.json +76 -0
- package/docs/schemas/memory-publish-target.schema.json +25 -0
- package/docs/schemas/multica-deployment-list.schema.json +29 -0
- package/docs/schemas/multica-deployment-operation.schema.json +51 -0
- package/docs/schemas/multica-deployment-plan.schema.json +70 -0
- package/docs/schemas/multica-deployment-receipt.schema.json +87 -0
- package/docs/schemas/multica-deployment-status.schema.json +23 -0
- package/docs/schemas/multica-workspace-inspection.schema.json +77 -0
- package/docs/schemas/multica-workspace-plan.schema.json +68 -0
- package/docs/schemas/multica-workspace-resource-list.schema.json +27 -0
- package/docs/schemas/multica-workspace-status.schema.json +34 -0
- package/docs/schemas/observation.schema.json +21 -0
- package/docs/schemas/operational-memory-provider.schema.json +36 -0
- package/docs/schemas/operational-memory-record.schema.json +24 -0
- package/docs/schemas/perception-input.schema.json +56 -0
- package/docs/schemas/project.schema.json +115 -0
- package/docs/schemas/promotion-list.schema.json +36 -0
- package/docs/schemas/promotion-plan.schema.json +60 -0
- package/docs/schemas/promotion-policy.schema.json +29 -0
- package/docs/schemas/promotion-receipt.schema.json +43 -0
- package/docs/schemas/promotion-status.schema.json +23 -0
- package/docs/schemas/release-readiness.schema.json +66 -0
- package/docs/schemas/remote-semantic-state-live-eval.schema.json +60 -0
- package/docs/schemas/remote-semantic-state-manifest.schema.json +79 -0
- package/docs/schemas/remote-semantic-state-provider.schema.json +98 -0
- package/docs/schemas/response-gate.schema.json +20 -0
- package/docs/schemas/task-checkpoint.schema.json +71 -0
- package/docs/schemas/task-completion-evidence.schema.json +154 -0
- package/docs/schemas/workspace-doctor.schema.json +56 -0
- package/docs/schemas/workspace-state.schema.json +39 -0
- package/evals/README.md +17 -0
- package/evals/baselines/2026-07-16/opencode-basic-010-completion-summary.json +123 -0
- package/evals/baselines/2026-07-16/opencode-basic-skill-required-summary.json +69 -0
- package/evals/baselines/2026-07-16/opencode-multi-surface-summary.json +63 -0
- package/evals/baselines/2026-07-16/remote-state-live-summary.json +70 -0
- package/evals/baselines/2026-07-17/agent-enhance-opencode-dogfood-summary.json +98 -0
- package/evals/baselines/2026-07-17/personal-event-live-readiness-summary.json +68 -0
- package/examples/agents/fde-coach/AGENTS.md +26 -0
- package/examples/agents/fde-coach/MEMORY.md +3 -0
- package/examples/agents/fde-coach/fields/default/field.json +24 -0
- package/examples/agents/fde-coach/knowledge/INDEX.md +4 -0
- package/examples/agents/fde-coach/skills/fde-coach/SKILL.md +13 -0
- package/examples/agents/release-manager/AGENTS.md +26 -0
- package/examples/agents/release-manager/MEMORY.md +3 -0
- package/examples/agents/release-manager/fields/default/field.json +24 -0
- package/examples/agents/release-manager/knowledge/INDEX.md +4 -0
- package/examples/agents/release-manager/skills/release-manager/SKILL.md +13 -0
- package/lab/README.md +109 -0
- package/lab/agent-eval/catalog.json +91 -0
- package/lab/agent-eval/classic-failures.json +177 -0
- package/lab/agent-eval/completion-gate-regression.json +99 -0
- package/lab/agent-eval/personal-event-live.example.json +94 -0
- package/lab/agent-eval/remote-semantic-state-live.example.json +70 -0
- package/lab/agent-eval/remote-semantic-state-provider.fixture.json +47 -0
- package/lab/agent-eval/remote-state-workspace/AGENTS.md +8 -0
- package/lab/agent-eval/remote-state-workspace/opencode.json +7 -0
- package/lab/agent-eval/remote-state-workspace/skills/remote-state-operator/SKILL.md +13 -0
- package/lab/agent-eval/remote-state.example.json +31 -0
- package/lab/agent-eval/workspace/AGENTS.md +7 -0
- package/lab/agent-eval/workspace/MEMORY.md +4 -0
- package/lab/agent-eval/workspace/artifacts/pending-review.md +3 -0
- package/lab/agent-eval/workspace/knowledge/INDEX.md +4 -0
- package/lab/agent-eval/workspace/opencode.json +20 -0
- package/lab/manifest.example.json +27 -0
- package/lab/manifest.personal-event.example.json +27 -0
- package/lab/project-workspace/README.md +11 -0
- package/lab/project-workspace/fake-multica-provider.mjs +277 -0
- package/lab/project-workspace/multica-deploy.fixture.json +29 -0
- package/lab/project-workspace/multica-readonly.fixture.json +69 -0
- package/lab/project-workspace/observation.fixture.json +14 -0
- package/lab/project-workspace/opencode-provider-suite.json +65 -0
- package/lab/project-workspace/project.fixture.json +44 -0
- package/lab/project-workspace/promotion-policy.fixture.json +15 -0
- package/lab/robot-eval/pool.example.json +30 -0
- package/lab/robot-eval/suite.json +123 -0
- package/lab/robot-eval/workspace/AGENTS.md +21 -0
- package/lab/robot-eval/workspace/MEMORY.md +3 -0
- package/lab/robot-eval/workspace/knowledge/INDEX.md +5 -0
- package/lab/robot-eval/workspace/opencode.json +22 -0
- package/lab/schemas/agent-eval-catalog.schema.json +47 -0
- package/lab/schemas/lab-manifest.schema.json +70 -0
- package/lab/schemas/personal-event-eval.schema.json +91 -0
- package/lab/schemas/remote-state-eval.schema.json +66 -0
- package/lab/schemas/robot-eval-suite.schema.json +184 -0
- package/lab/schemas/robot-pool.schema.json +56 -0
- package/package.json +28 -9
- package/skills/README.md +23 -0
- package/skills/core/dingtalk-agent-compose/SKILL.md +151 -0
- package/skills/core/dingtalk-agent-compose/assets/AGENTS.template.md +35 -0
- package/skills/core/dingtalk-agent-compose/assets/agent.bindings.dingtalk-doc.template.json +13 -0
- package/skills/core/dingtalk-agent-compose/assets/agent.bindings.local.template.json +13 -0
- package/skills/core/dingtalk-agent-compose/assets/hosts/opencode/opencode.template.json +12 -0
- package/skills/core/dingtalk-agent-compose/assets/role-skill.template.md +32 -0
- package/skills/core/dingtalk-agent-compose/evals/evals.json +129 -0
- package/skills/core/dingtalk-agent-compose/references/agent-definition-contract.md +55 -0
- package/skills/core/dingtalk-agent-compose/references/host-loading-contract.md +58 -0
- package/skills/core/dingtalk-agent-compose/references/hosts/claude-code.md +48 -0
- package/skills/core/dingtalk-agent-compose/references/hosts/opencode.md +77 -0
- package/skills/core/dingtalk-agent-compose/references/storage-routing.md +20 -0
- package/skills/core/dingtalk-agent-eval/SKILL.md +140 -0
- package/skills/core/dingtalk-agent-eval/assets/eval-catalog.template.json +18 -0
- package/skills/core/dingtalk-agent-eval/evals/evals.json +83 -0
- package/skills/core/dingtalk-agent-eval/references/eval-topology.md +48 -0
- package/skills/core/dingtalk-agent-eval/references/evidence-contract.md +52 -0
- package/skills/core/dingtalk-agent-eval/references/failure-to-case.md +35 -0
- package/skills/core/dingtalk-agent-eval/references/interactive-debug-channels.md +93 -0
- package/skills/core/dingtalk-agent-eval/references/local-connector-smoke.md +75 -0
- package/skills/core/dingtalk-agent-eval/references/scenario-taxonomy.md +25 -0
- package/skills/core/dingtalk-agent-eval/references/storage-modes.md +75 -0
- package/skills/core/dingtalk-basic-behavior/SKILL.md +87 -0
- package/skills/core/dingtalk-basic-behavior/assets/memory-candidate-proposal.json +10 -0
- package/skills/{dingtalk-basic-behavior/assets/task-checkpoint.md → core/dingtalk-basic-behavior/assets/task-checkpoint.json} +2 -21
- package/skills/{dingtalk-basic-behavior → core/dingtalk-basic-behavior}/references/action-contract.md +2 -0
- package/skills/core/dingtalk-basic-behavior/references/memory-and-evolution.md +53 -0
- package/skills/core/dingtalk-basic-behavior/references/perception-and-gates.md +28 -0
- package/skills/core/dingtalk-basic-behavior/references/risk-authority-and-privacy.md +62 -0
- package/skills/{dingtalk-basic-behavior → core/dingtalk-basic-behavior}/references/task-lifecycle.md +47 -10
- package/skills/core/dingtalk-basic-behavior/references/truth-and-recovery.md +65 -0
- package/skills/platforms/deap/PLATFORM.md +3 -0
- package/skills/platforms/deap/README.md +3 -0
- package/skills/platforms/multica-dingtalk/PLATFORM.md +40 -0
- package/skills/platforms/multica-dingtalk/dingtalk-agent-boot-multica/SKILL.md +40 -0
- package/skills/platforms/multica-dingtalk/dingtalk-agent-deploy-multica/SKILL.md +60 -0
- package/skills/platforms/multica-dingtalk/dingtalk-agent-deploy-multica/references/multica-deployment-contract.md +49 -0
- package/skills/platforms/multica-dingtalk/dingtalk-agent-deploy-multica/references/promotion-observation-contract.md +49 -0
- package/skills/platforms/multica-dingtalk/multica-external/SKILL.md +282 -0
- package/skills/platforms/multica-dingtalk/multica-external/scripts/bootstrap.sh +78 -0
- package/skills/platforms/multica-dingtalk/multica-external/scripts/multica_ext.py +1180 -0
- package/skills/dingtalk-basic-behavior/SKILL.md +0 -86
- package/skills/dingtalk-basic-behavior/references/memory-and-evolution.md +0 -27
- /package/skills/{dingtalk-basic-behavior → core/dingtalk-basic-behavior}/references/event-to-behavior.md +0 -0
- /package/skills/{dingtalk-basic-behavior → core/dingtalk-basic-behavior}/references/runtime-modes.md +0 -0
package/dist/src/bootstrap.js
CHANGED
|
@@ -4,22 +4,57 @@
|
|
|
4
4
|
// - local-dir 直接返回可读的 Markdown 挂载;
|
|
5
5
|
// - dingtalk-doc 通过 DWS 拉成隐藏的只读快照;
|
|
6
6
|
// - 已有 workspace@1 时复用其中的 mounts。
|
|
7
|
-
import { existsSync, lstatSync, mkdirSync, readFileSync, realpathSync, renameSync, writeFileSync, } from 'node:fs';
|
|
7
|
+
import { existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, realpathSync, renameSync, writeFileSync, } from 'node:fs';
|
|
8
8
|
import { basename, dirname, join, relative, resolve } from 'node:path';
|
|
9
9
|
import { digest } from './events.js';
|
|
10
10
|
import * as dws from './dws.js';
|
|
11
|
+
import { buildBootstrapDefinition } from './agent-definition.js';
|
|
12
|
+
import { directInvocation } from './invocation.js';
|
|
11
13
|
import { loadWorkspace, workspacePath } from './workspace.js';
|
|
12
14
|
export function bootstrap(root, options = {}) {
|
|
13
|
-
|
|
15
|
+
// Canonicalize aliases such as macOS /var -> /private/var so bootstrap,
|
|
16
|
+
// agent audit, evidence fingerprints, and later Session snapshots hash the
|
|
17
|
+
// same Agent root.
|
|
18
|
+
const cwd = realpathSync(resolve(root));
|
|
14
19
|
const hasWorkspace = existsSync(workspacePath(cwd));
|
|
15
20
|
const workspace = hasWorkspace ? loadWorkspace(cwd) : null;
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
const agent = select(options.agent || options.storage, options.context?.agent, process.env.DTA_AGENT_SOURCE, workspace ? 'workspace-manifest' : '', `local-dir:${cwd}`);
|
|
22
|
+
const memory = select(options.memory, options.context?.memory, process.env.DTA_MEMORY_STORAGE, workspace?.mounts.memory || '', existsSync(join(cwd, 'MEMORY.md')) ? 'local-md:MEMORY.md' : '');
|
|
23
|
+
const knowledge = select(options.knowledge, options.context?.knowledge, process.env.DTA_KNOWLEDGE_STORAGE, workspace?.mounts.knowledge || '', existsSync(join(cwd, 'knowledge', 'INDEX.md')) ? 'local-md:knowledge/INDEX.md' : '');
|
|
24
|
+
const skills = select(options.skills, options.context?.skills, process.env.DTA_SKILLS_SOURCE, workspace?.mounts.skills || '', existsSync(join(cwd, 'skills')) ? 'local-dir:skills' : '');
|
|
25
|
+
const state = select(options.stateDir, options.context?.stateDir, process.env.DTA_STATE_DIR, '', '.dingtalk-agent');
|
|
26
|
+
const artifacts = select(options.artifacts, options.context?.artifacts, process.env.DTA_ARTIFACTS_STORAGE, '', `local-dir:${resolve(cwd, state.value, 'artifacts')}`);
|
|
27
|
+
const dwsProfile = select(options.profile, options.context?.profile, process.env.DTA_DWS_PROFILE, workspace?.dws.profile || '', '');
|
|
28
|
+
const expectedUserId = select(options.expectedUserId, options.context?.expectedUserId, process.env.DTA_EXPECTED_USER_ID, workspace?.dws.expectedUserId || '', '');
|
|
29
|
+
const storage = agent.value;
|
|
30
|
+
const stateDir = resolve(cwd, state.value);
|
|
31
|
+
let mounts = workspace && agent.value === 'workspace-manifest'
|
|
32
|
+
? hydrateWorkspace(cwd, workspace, stateDir, dwsProfile.value, options.deferRemote)
|
|
33
|
+
: hydrateStorage(cwd, agent.value, stateDir, dwsProfile.value, 'body', options.deferRemote);
|
|
34
|
+
mounts = mergeMounts(mounts, hydrateOptional(cwd, memory.value, stateDir, dwsProfile.value, 'memory', options.deferRemote));
|
|
35
|
+
mounts = mergeMounts(mounts, hydrateOptional(cwd, knowledge.value, stateDir, dwsProfile.value, 'knowledge', options.deferRemote));
|
|
36
|
+
mounts = mergeMounts(mounts, hydrateOptional(cwd, skills.value, stateDir, dwsProfile.value, 'skills', options.deferRemote));
|
|
21
37
|
const contextId = workspace?.contextId || '';
|
|
22
|
-
const scopeSeed =
|
|
38
|
+
const scopeSeed = agent.value === 'workspace-manifest' && contextId
|
|
39
|
+
? contextId : canonicalStorageSeed(storage, cwd);
|
|
40
|
+
const sourcePath = storage.startsWith('local-dir:')
|
|
41
|
+
? safeLocalPath(cwd, parseStorage(storage).ref, true) : '';
|
|
42
|
+
const origins = {
|
|
43
|
+
agent: agent.origin, memory: memory.origin, knowledge: knowledge.origin,
|
|
44
|
+
skills: skills.origin, artifacts: artifacts.origin, state: state.origin,
|
|
45
|
+
dwsProfile: dwsProfile.origin, expectedUserId: expectedUserId.origin,
|
|
46
|
+
};
|
|
47
|
+
const definition = buildBootstrapDefinition(mounts, {
|
|
48
|
+
source: storage,
|
|
49
|
+
sourcePath,
|
|
50
|
+
memory: memory.value,
|
|
51
|
+
knowledge: knowledge.value,
|
|
52
|
+
artifacts: artifacts.value,
|
|
53
|
+
state: stateDir,
|
|
54
|
+
dwsProfile: dwsProfile.value,
|
|
55
|
+
expectedUserId: expectedUserId.value,
|
|
56
|
+
origins,
|
|
57
|
+
}, agent.value === 'workspace-manifest' ? workspace : null);
|
|
23
58
|
return {
|
|
24
59
|
$schema: 'dingtalk-agent/bootstrap@1',
|
|
25
60
|
mode: workspace ? 'workspace' : 'direct',
|
|
@@ -29,29 +64,42 @@ export function bootstrap(root, options = {}) {
|
|
|
29
64
|
storage,
|
|
30
65
|
stateDir: mounts.some((item) => item.provider === 'dingtalk-doc') ? stateDir : '',
|
|
31
66
|
mounts,
|
|
67
|
+
definition,
|
|
68
|
+
invocation: directInvocation(),
|
|
32
69
|
note: hasWorkspace
|
|
33
70
|
? '已读取现有 Workspace;init 不是每次 Session 的前置动作。'
|
|
34
71
|
: '未初始化 Workspace;已按直接会话模式工作,不会自动修改当前目录。',
|
|
35
72
|
};
|
|
36
73
|
}
|
|
37
|
-
function hydrateWorkspace(root, workspace, stateDir, profile = '') {
|
|
74
|
+
function hydrateWorkspace(root, workspace, stateDir, profile = '', deferRemote = false) {
|
|
38
75
|
const out = [];
|
|
39
76
|
for (const slot of ['profile', 'memory', 'knowledge']) {
|
|
40
|
-
out.push(...hydrateStorage(root, workspace.mounts[slot], stateDir, profile || workspace.dws.profile, slot));
|
|
77
|
+
out.push(...hydrateStorage(root, workspace.mounts[slot], stateDir, profile || workspace.dws.profile, slot, deferRemote));
|
|
41
78
|
}
|
|
42
79
|
return out;
|
|
43
80
|
}
|
|
44
|
-
function hydrateStorage(root, uri, stateDir, profile = '', slot = 'workspace') {
|
|
81
|
+
function hydrateStorage(root, uri, stateDir, profile = '', slot = 'workspace', deferRemote = false) {
|
|
45
82
|
const mount = parseStorage(uri);
|
|
46
|
-
if (mount.provider === 'local-dir')
|
|
47
|
-
|
|
83
|
+
if (mount.provider === 'local-dir') {
|
|
84
|
+
if (slot === 'skills') {
|
|
85
|
+
return discoverSkillDirectory(root, mount.ref);
|
|
86
|
+
}
|
|
87
|
+
const discovered = discoverLocalDirectory(root, mount.ref);
|
|
88
|
+
return slot === 'body' || slot === 'workspace'
|
|
89
|
+
? discovered
|
|
90
|
+
: discovered.filter((item) => item.slot === slot);
|
|
91
|
+
}
|
|
48
92
|
if (mount.provider === 'local-md') {
|
|
49
93
|
const path = safeLocalPath(root, mount.ref, false);
|
|
50
94
|
if (!path)
|
|
51
95
|
return [];
|
|
52
96
|
const markdown = readFileSync(path, 'utf8');
|
|
53
|
-
|
|
97
|
+
const effectiveSlot = slot === 'skills'
|
|
98
|
+
? `skill:${readSkillName(markdown) || safeName(path)}` : slot;
|
|
99
|
+
return [{ slot: effectiveSlot, provider: mount.provider, source: uri, path, hash: digest(markdown) }];
|
|
54
100
|
}
|
|
101
|
+
if (deferRemote)
|
|
102
|
+
return [];
|
|
55
103
|
// /i/nodes URL 是多产品统一入口;先 probe,只有在线文档 adoc 才能作为 Markdown Storage。
|
|
56
104
|
const info = dws.docInfo(mount.ref, profile);
|
|
57
105
|
const contentType = String(info?.contentType || '').toUpperCase();
|
|
@@ -61,8 +109,14 @@ function hydrateStorage(root, uri, stateDir, profile = '', slot = 'workspace') {
|
|
|
61
109
|
}
|
|
62
110
|
const markdown = String(dws.readDoc(mount.ref, profile));
|
|
63
111
|
const scope = digest(uri).slice(0, 20);
|
|
64
|
-
const
|
|
65
|
-
|
|
112
|
+
const effectiveSlot = slot === 'skills'
|
|
113
|
+
? `skill:${readSkillName(markdown) || safeName(mount.ref)}` : slot;
|
|
114
|
+
// A single remote document may intentionally back more than one semantic slot.
|
|
115
|
+
// Give each slot its own directory so its manifest cannot overwrite another slot.
|
|
116
|
+
const path = join(stateDir, 'cache', 'bootstrap', scope, safeName(effectiveSlot), 'snapshot.md');
|
|
117
|
+
// Cache bytes must be identical to the independently read remote bytes. Adding
|
|
118
|
+
// formatting here would make the manifest hash describe data that is not on disk.
|
|
119
|
+
writeAtomic(path, markdown);
|
|
66
120
|
const manifest = join(dirname(path), 'manifest.json');
|
|
67
121
|
writeAtomic(manifest, JSON.stringify({
|
|
68
122
|
$schema: 'dingtalk-agent/bootstrap-cache@1',
|
|
@@ -72,7 +126,7 @@ function hydrateStorage(root, uri, stateDir, profile = '', slot = 'workspace') {
|
|
|
72
126
|
hash: digest(markdown),
|
|
73
127
|
path,
|
|
74
128
|
}, null, 2) + '\n');
|
|
75
|
-
return [{ slot, provider: mount.provider, source: uri, path, hash: digest(markdown) }];
|
|
129
|
+
return [{ slot: effectiveSlot, provider: mount.provider, source: uri, path, hash: digest(markdown) }];
|
|
76
130
|
}
|
|
77
131
|
function discoverLocalDirectory(root, ref) {
|
|
78
132
|
const directory = safeLocalPath(root, ref, true);
|
|
@@ -80,6 +134,7 @@ function discoverLocalDirectory(root, ref) {
|
|
|
80
134
|
throw new Error(`local-dir 不是目录: ${ref}`);
|
|
81
135
|
}
|
|
82
136
|
const candidates = [
|
|
137
|
+
['body', 'AGENTS.md'],
|
|
83
138
|
['profile', 'WORKSPACE.md'],
|
|
84
139
|
['memory', 'MEMORY.md'],
|
|
85
140
|
['knowledge', join('knowledge', 'INDEX.md')],
|
|
@@ -98,8 +153,61 @@ function discoverLocalDirectory(root, ref) {
|
|
|
98
153
|
hash: digest(markdown),
|
|
99
154
|
});
|
|
100
155
|
}
|
|
156
|
+
out.push(...discoverSkillDirectory(root, join(directory, 'skills'), true));
|
|
101
157
|
return out;
|
|
102
158
|
}
|
|
159
|
+
function discoverSkillDirectory(root, ref, optional = false) {
|
|
160
|
+
const candidate = resolve(root, ref);
|
|
161
|
+
if (!existsSync(candidate)) {
|
|
162
|
+
if (optional)
|
|
163
|
+
return [];
|
|
164
|
+
throw new Error(`Skill Storage 不存在: ${ref}`);
|
|
165
|
+
}
|
|
166
|
+
const directory = realpathSync(candidate);
|
|
167
|
+
if (!lstatSync(directory).isDirectory())
|
|
168
|
+
throw new Error(`Skill Storage 不是目录: ${ref}`);
|
|
169
|
+
const roots = existsSync(join(directory, 'SKILL.md'))
|
|
170
|
+
? [directory]
|
|
171
|
+
: readdirSync(directory).sort().map((name) => join(directory, name))
|
|
172
|
+
.filter((path) => existsSync(join(path, 'SKILL.md')) && lstatSync(path).isDirectory());
|
|
173
|
+
return roots.map((path) => {
|
|
174
|
+
const markdown = readFileSync(join(path, 'SKILL.md'), 'utf8');
|
|
175
|
+
const name = readSkillName(markdown) || basename(path);
|
|
176
|
+
return {
|
|
177
|
+
slot: `skill:${name}`, provider: 'local-dir',
|
|
178
|
+
source: `local-dir:${directory}`, path: join(path, 'SKILL.md'), hash: digest(markdown),
|
|
179
|
+
};
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
function hydrateOptional(root, uri, stateDir, profile, slot, deferRemote = false) {
|
|
183
|
+
return uri ? hydrateStorage(root, uri, stateDir, profile, slot, deferRemote) : [];
|
|
184
|
+
}
|
|
185
|
+
function mergeMounts(current, additions) {
|
|
186
|
+
const out = [...current];
|
|
187
|
+
for (const addition of additions) {
|
|
188
|
+
const index = out.findIndex((item) => item.slot === addition.slot);
|
|
189
|
+
if (index >= 0)
|
|
190
|
+
out[index] = addition;
|
|
191
|
+
else
|
|
192
|
+
out.push(addition);
|
|
193
|
+
}
|
|
194
|
+
return out;
|
|
195
|
+
}
|
|
196
|
+
function readSkillName(markdown) {
|
|
197
|
+
const frontmatter = markdown.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
198
|
+
return frontmatter?.[1].match(/^name:\s*['"]?([^'"\r\n]+)['"]?\s*$/m)?.[1]?.trim() || '';
|
|
199
|
+
}
|
|
200
|
+
function select(explicit, context, environment, workspace, convention) {
|
|
201
|
+
const choices = [
|
|
202
|
+
[explicit, 'explicit'], [context, 'context'], [environment, 'environment'],
|
|
203
|
+
[workspace, 'workspace'], [convention, 'convention'],
|
|
204
|
+
];
|
|
205
|
+
for (const [value, origin] of choices) {
|
|
206
|
+
if (typeof value === 'string' && value.trim())
|
|
207
|
+
return { value: value.trim(), origin };
|
|
208
|
+
}
|
|
209
|
+
return { value: '', origin: 'convention' };
|
|
210
|
+
}
|
|
103
211
|
function parseStorage(uri) {
|
|
104
212
|
const separator = uri.indexOf(':');
|
|
105
213
|
const provider = separator < 0 ? '' : uri.slice(0, separator);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/bootstrap.ts"],"names":[],"mappings":"AAAA,yBAAyB;AACzB,EAAE;AACF,sBAAsB;AACtB,mCAAmC;AACnC,mCAAmC;AACnC,kCAAkC;AAElC,OAAO,EACL,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EACxE,aAAa,GACd,MAAM,SAAS,CAAA;AAChB,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACtE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA;AAC/B,OAAO,EAAE,aAAa,EAAE,aAAa,EAAsB,MAAM,gBAAgB,CAAA;AA8BjF,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,UAA4B,EAAE;IACpE,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACzB,MAAM,YAAY,GAAG,UAAU,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAA;IACnD,MAAM,SAAS,GAAG,YAAY,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IAC1D,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,aAAa,GAAG,EAAE,CAAC,CAAA;IAClG,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,iBAAiB,CAAC,CAAA;IACjG,MAAM,MAAM,GAAG,SAAS,IAAI,CAAC,OAAO,CAAC,OAAO;QAC1C,CAAC,CAAC,gBAAgB,CAAC,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC;QAC7D,CAAC,CAAC,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;IACxE,MAAM,SAAS,GAAG,SAAS,EAAE,SAAS,IAAI,EAAE,CAAA;IAC5C,MAAM,SAAS,GAAG,SAAS,IAAI,oBAAoB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;IACjE,OAAO;QACL,OAAO,EAAE,4BAA4B;QACrC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ;QACxC,WAAW,EAAE,YAAY;QACzB,OAAO,EAAE,SAAS,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE;QAClD,SAAS;QACT,OAAO;QACP,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,KAAK,cAAc,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE;QACjF,MAAM;QACN,IAAI,EAAE,YAAY;YAChB,CAAC,CAAC,0CAA0C;YAC5C,CAAC,CAAC,uCAAuC;KAC5C,CAAA;AACH,CAAC;AAED,SAAS,gBAAgB,CACvB,IAAY,EACZ,SAAwB,EACxB,QAAgB,EAChB,OAAO,GAAG,EAAE;IAEZ,MAAM,GAAG,GAAqB,EAAE,CAAA;IAChC,KAAK,MAAM,IAAI,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,WAAW,CAAU,EAAE,CAAC;QAC/D,GAAG,CAAC,IAAI,CAAC,GAAG,cAAc,CACxB,IAAI,EACJ,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,EACtB,QAAQ,EACR,OAAO,IAAI,SAAS,CAAC,GAAG,CAAC,OAAO,EAChC,IAAI,CACL,CAAC,CAAA;IACJ,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,SAAS,cAAc,CACrB,IAAY,EACZ,GAAW,EACX,QAAgB,EAChB,OAAO,GAAG,EAAE,EACZ,IAAI,GAAG,WAAW;IAElB,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,CAAA;IAC/B,IAAI,KAAK,CAAC,QAAQ,KAAK,WAAW;QAAE,OAAO,sBAAsB,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAA;IAClF,IAAI,KAAK,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;QAClD,IAAI,CAAC,IAAI;YAAE,OAAO,EAAE,CAAA;QACpB,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QAC3C,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;IACxF,CAAC;IAED,mEAAmE;IACnE,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;IAC5C,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,EAAE,WAAW,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAA;IACjE,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,EAAE,SAAS,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAA;IAC7D,IAAI,WAAW,KAAK,QAAQ,IAAI,SAAS,KAAK,MAAM,EAAE,CAAC;QACrD,MAAM,IAAI,KAAK,CACb,4CAA4C,WAAW,IAAI,GAAG,cAAc,SAAS,IAAI,GAAG,EAAE,CAC/F,CAAA;IACH,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;IACxD,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;IACtC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAChF,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,IAAI,CAAC,CAAA;IACvE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,eAAe,CAAC,CAAA;IACrD,WAAW,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC;QACnC,OAAO,EAAE,kCAAkC;QAC3C,MAAM,EAAE,GAAG;QACX,OAAO;QACP,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAClC,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC;QACtB,IAAI;KACL,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;IACnB,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;AACxF,CAAC;AAED,SAAS,sBAAsB,CAAC,IAAY,EAAE,GAAW;IACvD,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAChD,IAAI,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;QACtD,MAAM,IAAI,KAAK,CAAC,mBAAmB,GAAG,EAAE,CAAC,CAAA;IAC3C,CAAC;IACD,MAAM,UAAU,GAA4B;QAC1C,CAAC,SAAS,EAAE,cAAc,CAAC;QAC3B,CAAC,QAAQ,EAAE,WAAW,CAAC;QACvB,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;KAC7C,CAAA;IACD,MAAM,GAAG,GAAqB,EAAE,CAAA;IAChC,KAAK,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,UAAU,EAAE,CAAC;QACrC,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAA;QACpC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE;YAAE,SAAQ;QAC5D,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QAC3C,GAAG,CAAC,IAAI,CAAC;YACP,IAAI;YACJ,QAAQ,EAAE,WAAW;YACrB,MAAM,EAAE,aAAa,SAAS,EAAE;YAChC,IAAI;YACJ,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC;SACvB,CAAC,CAAA;IACJ,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,SAAS,YAAY,CAAC,GAAW;IAC/B,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAClC,MAAM,QAAQ,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAA;IAC7D,MAAM,GAAG,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;IAChE,IAAI,CAAC,CAAC,WAAW,EAAE,UAAU,EAAE,cAAc,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QAC1E,MAAM,IAAI,KAAK,CACb,oBAAoB,GAAG,qEAAqE,CAC7F,CAAA;IACH,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,QAAoB,EAAE,GAAG,EAAE,CAAA;AAChD,CAAC;AAED,SAAS,aAAa,CAAC,IAAY,EAAE,GAAW,EAAE,aAAsB;IACtE,MAAM,QAAQ,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAA;IAC5C,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAA;IACxC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3B,IAAI,CAAC,aAAa;YAAE,OAAO,EAAE,CAAA;QAC7B,MAAM,IAAI,KAAK,CAAC,gBAAgB,GAAG,EAAE,CAAC,CAAA;IACxC,CAAC;IACD,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,CAAA;IACtC,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,GAAG,GAAG,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;QACtC,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,CAAC,UAAU,CAAC,KAAK,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC;YACrF,MAAM,IAAI,KAAK,CAAC,gCAAgC,GAAG,EAAE,CAAC,CAAA;QACxD,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED,SAAS,oBAAoB,CAAC,OAAe,EAAE,IAAY;IACzD,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,CAAA;IACnC,OAAO,KAAK,CAAC,QAAQ,KAAK,WAAW;QACnC,CAAC,CAAC,aAAa,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE;QACvD,CAAC,CAAC,OAAO,CAAA;AACb,CAAC;AAED,SAAS,WAAW,CAAC,IAAY,EAAE,KAAa;IAC9C,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAC7C,MAAM,IAAI,GAAG,GAAG,IAAI,IAAI,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,MAAM,CAAA;IACvD,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;IAC1C,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;AACxB,CAAC;AAED,SAAS,QAAQ,CAAC,KAAa;IAC7B,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,mBAAmB,EAAE,GAAG,CAAC,IAAI,WAAW,CAAA;AACzE,CAAC","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, 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 { loadWorkspace, workspacePath, type WorkspaceSpec } from './workspace.js'\n\ntype Provider = 'local-dir' | 'local-md' | 'dingtalk-doc'\n\nexport interface BootstrapOptions {\n storage?: string\n stateDir?: string\n profile?: string\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 note: string\n}\n\nexport function bootstrap(root: string, options: BootstrapOptions = {}): BootstrapResult {\n const cwd = resolve(root)\n const hasWorkspace = existsSync(workspacePath(cwd))\n const workspace = hasWorkspace ? loadWorkspace(cwd) : null\n const storage = options.storage?.trim() || (workspace ? 'workspace-manifest' : `local-dir:${cwd}`)\n const stateDir = resolve(cwd, options.stateDir || process.env.DTA_STATE_DIR || '.dingtalk-agent')\n const mounts = workspace && !options.storage\n ? hydrateWorkspace(cwd, workspace, stateDir, options.profile)\n : hydrateStorage(cwd, storage, stateDir, options.profile, 'workspace')\n const contextId = workspace?.contextId || ''\n const scopeSeed = contextId || canonicalStorageSeed(storage, cwd)\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 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): 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 ))\n }\n return out\n}\n\nfunction hydrateStorage(\n root: string,\n uri: string,\n stateDir: string,\n profile = '',\n slot = 'workspace',\n): BootstrapMount[] {\n const mount = parseStorage(uri)\n if (mount.provider === 'local-dir') return discoverLocalDirectory(root, mount.ref)\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 return [{ slot, provider: mount.provider, source: uri, path, hash: digest(markdown) }]\n }\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 path = join(stateDir, 'cache', 'bootstrap', scope, `${safeName(slot)}.md`)\n writeAtomic(path, markdown.endsWith('\\n') ? markdown : `${markdown}\\n`)\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, 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 ['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 return out\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 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"]}
|
package/dist/src/config.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// 配置 —— CLI 记住的东西(TypeScript source)。
|
|
2
2
|
//
|
|
3
|
-
// **记什么**:身份 ·
|
|
3
|
+
// **记什么**:身份 · DWS 绑定 · 运行时根目录 · Field 挂载。
|
|
4
4
|
// **不记什么**:凭证(那是 dws 的事,别在这里存 token)。
|
|
5
5
|
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
|
|
6
6
|
import { join, dirname, resolve, parse } from 'node:path';
|
|
@@ -26,9 +26,6 @@ export const DEFAULT = {
|
|
|
26
26
|
fields: [
|
|
27
27
|
{ id: 'default', path: 'fields/default/field.json', default: true, priority: 0 },
|
|
28
28
|
],
|
|
29
|
-
kb: [],
|
|
30
|
-
duties: [],
|
|
31
|
-
eval: { target: '' },
|
|
32
29
|
};
|
|
33
30
|
export const path = (root) => join(root, FILE);
|
|
34
31
|
/**
|
|
@@ -58,9 +55,6 @@ export function normalize(input = {}) {
|
|
|
58
55
|
fields: value.fields === undefined
|
|
59
56
|
? DEFAULT.fields.map((x) => ({ ...x }))
|
|
60
57
|
: (Array.isArray(value.fields) ? value.fields : []),
|
|
61
|
-
kb: Array.isArray(value.kb) ? value.kb : [],
|
|
62
|
-
duties: Array.isArray(value.duties) ? value.duties : [],
|
|
63
|
-
eval: { ...DEFAULT.eval, ...(isRecord(value.eval) ? value.eval : {}) },
|
|
64
58
|
};
|
|
65
59
|
}
|
|
66
60
|
export function load(root) {
|
package/dist/src/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,EAAE;AACF,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["// 配置 —— CLI 记住的东西(TypeScript source)。\n//\n// **记什么**:身份 · DWS 绑定 · 运行时根目录 · Field 挂载。\n// **不记什么**:凭证(那是 dws 的事,别在这里存 token)。\nimport { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs'\nimport { join, dirname, resolve, parse } from 'node:path'\nimport type { AgentConfig } from './types.js'\n\nexport const FILE = '.dingtalk-agent/config.json'\n\nexport const DEFAULT: AgentConfig = {\n schemaVersion: 2,\n agent: {\n name: '<还没起名>',\n userId: '<从 dws contact 取,不要猜>',\n ownerId: '<主人的 userId>',\n },\n dws: {\n // 外发前二者都必须固定;留空只允许 prepare/silence,不允许消息外发。\n profile: '',\n expectedUserId: '',\n },\n runtime: {\n sessionRoot: '.dingtalk-agent/sessions',\n eventIndexRoot: '.dingtalk-agent/event-index',\n waitRoot: '.dingtalk-agent/waits',\n waitTtlMs: 604800000,\n },\n fields: [\n { id: 'default', path: 'fields/default/field.json', default: true, priority: 0 },\n ],\n}\n\nexport const path = (root: string): string => join(root, FILE)\n\n/**\n * 沙箱 cwd 往往落在 Session/Run 子目录里,不能再假设 cwd 就是工作区根。\n * 显式 DTA_ROOT 优先;否则向上寻找配置。init 场景找不到时由调用方回退到 cwd。\n */\nexport function findRoot(start = process.cwd()): string | null {\n let dir = resolve(start)\n while (true) {\n if (existsSync(path(dir))) return dir\n const parent = dirname(dir)\n if (parent === dir || dir === parse(dir).root) return null\n dir = parent\n }\n}\n\n/** 老工作区按默认值补齐新字段,但绝不覆盖已有配置。 */\nexport function normalize(input: unknown = {}): AgentConfig {\n const value = isRecord(input) ? input : {}\n return {\n ...DEFAULT,\n ...value,\n agent: { ...DEFAULT.agent, ...(isRecord(value.agent) ? value.agent : {}) },\n dws: { ...DEFAULT.dws, ...(isRecord(value.dws) ? value.dws : {}) },\n runtime: { ...DEFAULT.runtime, ...(isRecord(value.runtime) ? value.runtime : {}) },\n fields: value.fields === undefined\n ? DEFAULT.fields.map((x) => ({ ...x }))\n : (Array.isArray(value.fields) ? value.fields as AgentConfig['fields'] : []),\n }\n}\n\nexport function load(root: string): AgentConfig | null {\n const p = path(root)\n return existsSync(p) ? normalize(JSON.parse(readFileSync(p, 'utf8'))) : null\n}\n\nexport function save(root: string, value: unknown): void {\n const p = path(root)\n mkdirSync(dirname(p), { recursive: true })\n writeFileSync(p, JSON.stringify(normalize(value), null, 2) + '\\n')\n}\n\nexport function must(root: string): AgentConfig {\n const cfg = load(root)\n if (!cfg) {\n throw new Error(\n 'Prepared Run runtime 尚未初始化 —— 先跑一次 `dingtalk-agent init`。\\n' +\n ' 普通 Agent Session 不需要 init;请使用全局 Skill,并按需运行 `dingtalk-agent bootstrap`。')\n }\n return cfg\n}\n\nfunction isRecord(value: unknown): value is Record<string, any> {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value)\n}\n"]}
|