@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.
Files changed (254) hide show
  1. package/CHANGELOG.md +233 -0
  2. package/README.en.md +167 -0
  3. package/README.md +101 -248
  4. package/dist/bin/dingtalk-agent.js +1255 -25
  5. package/dist/bin/dingtalk-agent.js.map +1 -1
  6. package/dist/src/actions.js +98 -14
  7. package/dist/src/actions.js.map +1 -1
  8. package/dist/src/agent-audit.js +1385 -0
  9. package/dist/src/agent-audit.js.map +1 -0
  10. package/dist/src/agent-bindings.js +132 -0
  11. package/dist/src/agent-bindings.js.map +1 -0
  12. package/dist/src/agent-definition.js +182 -0
  13. package/dist/src/agent-definition.js.map +1 -0
  14. package/dist/src/agent-enhance.js +711 -0
  15. package/dist/src/agent-enhance.js.map +1 -0
  16. package/dist/src/agent-platform.js +299 -0
  17. package/dist/src/agent-platform.js.map +1 -0
  18. package/dist/src/bootstrap.js +125 -17
  19. package/dist/src/bootstrap.js.map +1 -1
  20. package/dist/src/config.js +1 -7
  21. package/dist/src/config.js.map +1 -1
  22. package/dist/src/development-workspace.js +755 -0
  23. package/dist/src/development-workspace.js.map +1 -0
  24. package/dist/src/doctor.js +74 -15
  25. package/dist/src/doctor.js.map +1 -1
  26. package/dist/src/dws.js +145 -0
  27. package/dist/src/dws.js.map +1 -1
  28. package/dist/src/eval-evidence.js +193 -0
  29. package/dist/src/eval-evidence.js.map +1 -0
  30. package/dist/src/host-detect.js +146 -0
  31. package/dist/src/host-detect.js.map +1 -0
  32. package/dist/src/instruction-path.js +270 -0
  33. package/dist/src/instruction-path.js.map +1 -0
  34. package/dist/src/invocation.js +36 -0
  35. package/dist/src/invocation.js.map +1 -0
  36. package/dist/src/lab.js +679 -0
  37. package/dist/src/lab.js.map +1 -0
  38. package/dist/src/lease.js +100 -0
  39. package/dist/src/lease.js.map +1 -0
  40. package/dist/src/map.js +157 -0
  41. package/dist/src/map.js.map +1 -0
  42. package/dist/src/memory/candidates.js +451 -0
  43. package/dist/src/memory/candidates.js.map +1 -0
  44. package/dist/src/memory/completion-evidence.js +536 -0
  45. package/dist/src/memory/completion-evidence.js.map +1 -0
  46. package/dist/src/memory/operational.js +263 -0
  47. package/dist/src/memory/operational.js.map +1 -0
  48. package/dist/src/memory/remote-state.js +478 -0
  49. package/dist/src/memory/remote-state.js.map +1 -0
  50. package/dist/src/memory/task-checkpoints.js +204 -0
  51. package/dist/src/memory/task-checkpoints.js.map +1 -0
  52. package/dist/src/multica-deploy.js +1538 -0
  53. package/dist/src/multica-deploy.js.map +1 -0
  54. package/dist/src/multica-provider.js +685 -0
  55. package/dist/src/multica-provider.js.map +1 -0
  56. package/dist/src/opencode-evals.js +1547 -0
  57. package/dist/src/opencode-evals.js.map +1 -0
  58. package/dist/src/opencode-isolation.js +124 -0
  59. package/dist/src/opencode-isolation.js.map +1 -0
  60. package/dist/src/opencode-provider.js +532 -0
  61. package/dist/src/opencode-provider.js.map +1 -0
  62. package/dist/src/opencode-workspace.js +208 -0
  63. package/dist/src/opencode-workspace.js.map +1 -0
  64. package/dist/src/perception.js +225 -0
  65. package/dist/src/perception.js.map +1 -0
  66. package/dist/src/personal-event-evals.js +595 -0
  67. package/dist/src/personal-event-evals.js.map +1 -0
  68. package/dist/src/promotion.js +786 -0
  69. package/dist/src/promotion.js.map +1 -0
  70. package/dist/src/remote-semantic-state-live-evals.js +888 -0
  71. package/dist/src/remote-semantic-state-live-evals.js.map +1 -0
  72. package/dist/src/remote-semantic-state-worker.js +38 -0
  73. package/dist/src/remote-semantic-state-worker.js.map +1 -0
  74. package/dist/src/remote-state-evals.js +502 -0
  75. package/dist/src/remote-state-evals.js.map +1 -0
  76. package/dist/src/response-gate.js +51 -0
  77. package/dist/src/response-gate.js.map +1 -0
  78. package/dist/src/robot-evals.js +771 -0
  79. package/dist/src/robot-evals.js.map +1 -0
  80. package/dist/src/sessions.js +66 -105
  81. package/dist/src/sessions.js.map +1 -1
  82. package/dist/src/setup.js +6 -5
  83. package/dist/src/setup.js.map +1 -1
  84. package/dist/src/skill-manager.js +162 -24
  85. package/dist/src/skill-manager.js.map +1 -1
  86. package/dist/src/skills.js +2 -1
  87. package/dist/src/skills.js.map +1 -1
  88. package/dist/src/storage-evals.js +26 -0
  89. package/dist/src/storage-evals.js.map +1 -0
  90. package/dist/src/types.js.map +1 -1
  91. package/dist/src/upgrade.js +23 -27
  92. package/dist/src/upgrade.js.map +1 -1
  93. package/dist/src/version.js +73 -0
  94. package/dist/src/version.js.map +1 -0
  95. package/dist/src/waits.js +5 -1
  96. package/dist/src/waits.js.map +1 -1
  97. package/dist/src/workspace.js +28 -3
  98. package/dist/src/workspace.js.map +1 -1
  99. package/docs/INSTALLATION.md +50 -3
  100. package/docs/SECOND-AGENT-ACCEPTANCE.md +62 -0
  101. package/docs/architecture/agent-memory-topology.png +0 -0
  102. package/docs/architecture/agent-memory-topology.svg +132 -0
  103. package/docs/architecture/general-agent-kernel-topology.png +0 -0
  104. package/docs/architecture/general-agent-kernel-topology.svg +149 -0
  105. package/docs/architecture/provider-bound-development-workspace.png +0 -0
  106. package/docs/architecture/provider-bound-development-workspace.svg +141 -0
  107. package/docs/architecture/task-completion-gate.png +0 -0
  108. package/docs/architecture/task-completion-gate.svg +191 -0
  109. package/docs/assets/agent-delivery-lifecycle.svg +103 -0
  110. package/docs/schemas/agent-audit-load-evidence.schema.json +14 -0
  111. package/docs/schemas/agent-audit.schema.json +92 -0
  112. package/docs/schemas/agent-bindings.schema.json +54 -0
  113. package/docs/schemas/agent-definition.schema.json +78 -0
  114. package/docs/schemas/agent-enhancement-plan.schema.json +88 -0
  115. package/docs/schemas/agent-enhancement-receipt.schema.json +37 -0
  116. package/docs/schemas/agent-platform.schema.json +13 -0
  117. package/docs/schemas/enriched-invocation.schema.json +46 -0
  118. package/docs/schemas/eval-candidate-plan.schema.json +28 -0
  119. package/docs/schemas/eval-candidate-result.schema.json +20 -0
  120. package/docs/schemas/eval-candidate.schema.json +30 -0
  121. package/docs/schemas/invocation.schema.json +19 -0
  122. package/docs/schemas/memory-candidate-proposal.schema.json +18 -0
  123. package/docs/schemas/memory-candidate.schema.json +76 -0
  124. package/docs/schemas/memory-publish-target.schema.json +25 -0
  125. package/docs/schemas/multica-deployment-list.schema.json +29 -0
  126. package/docs/schemas/multica-deployment-operation.schema.json +51 -0
  127. package/docs/schemas/multica-deployment-plan.schema.json +70 -0
  128. package/docs/schemas/multica-deployment-receipt.schema.json +87 -0
  129. package/docs/schemas/multica-deployment-status.schema.json +23 -0
  130. package/docs/schemas/multica-workspace-inspection.schema.json +77 -0
  131. package/docs/schemas/multica-workspace-plan.schema.json +68 -0
  132. package/docs/schemas/multica-workspace-resource-list.schema.json +27 -0
  133. package/docs/schemas/multica-workspace-status.schema.json +34 -0
  134. package/docs/schemas/observation.schema.json +21 -0
  135. package/docs/schemas/operational-memory-provider.schema.json +36 -0
  136. package/docs/schemas/operational-memory-record.schema.json +24 -0
  137. package/docs/schemas/perception-input.schema.json +56 -0
  138. package/docs/schemas/project.schema.json +115 -0
  139. package/docs/schemas/promotion-list.schema.json +36 -0
  140. package/docs/schemas/promotion-plan.schema.json +60 -0
  141. package/docs/schemas/promotion-policy.schema.json +29 -0
  142. package/docs/schemas/promotion-receipt.schema.json +43 -0
  143. package/docs/schemas/promotion-status.schema.json +23 -0
  144. package/docs/schemas/release-readiness.schema.json +66 -0
  145. package/docs/schemas/remote-semantic-state-live-eval.schema.json +60 -0
  146. package/docs/schemas/remote-semantic-state-manifest.schema.json +79 -0
  147. package/docs/schemas/remote-semantic-state-provider.schema.json +98 -0
  148. package/docs/schemas/response-gate.schema.json +20 -0
  149. package/docs/schemas/task-checkpoint.schema.json +71 -0
  150. package/docs/schemas/task-completion-evidence.schema.json +154 -0
  151. package/docs/schemas/workspace-doctor.schema.json +56 -0
  152. package/docs/schemas/workspace-state.schema.json +39 -0
  153. package/evals/README.md +17 -0
  154. package/evals/baselines/2026-07-16/opencode-basic-010-completion-summary.json +123 -0
  155. package/evals/baselines/2026-07-16/opencode-basic-skill-required-summary.json +69 -0
  156. package/evals/baselines/2026-07-16/opencode-multi-surface-summary.json +63 -0
  157. package/evals/baselines/2026-07-16/remote-state-live-summary.json +70 -0
  158. package/evals/baselines/2026-07-17/agent-enhance-opencode-dogfood-summary.json +98 -0
  159. package/evals/baselines/2026-07-17/personal-event-live-readiness-summary.json +68 -0
  160. package/examples/agents/fde-coach/AGENTS.md +26 -0
  161. package/examples/agents/fde-coach/MEMORY.md +3 -0
  162. package/examples/agents/fde-coach/fields/default/field.json +24 -0
  163. package/examples/agents/fde-coach/knowledge/INDEX.md +4 -0
  164. package/examples/agents/fde-coach/skills/fde-coach/SKILL.md +13 -0
  165. package/examples/agents/release-manager/AGENTS.md +26 -0
  166. package/examples/agents/release-manager/MEMORY.md +3 -0
  167. package/examples/agents/release-manager/fields/default/field.json +24 -0
  168. package/examples/agents/release-manager/knowledge/INDEX.md +4 -0
  169. package/examples/agents/release-manager/skills/release-manager/SKILL.md +13 -0
  170. package/lab/README.md +109 -0
  171. package/lab/agent-eval/catalog.json +91 -0
  172. package/lab/agent-eval/classic-failures.json +177 -0
  173. package/lab/agent-eval/completion-gate-regression.json +99 -0
  174. package/lab/agent-eval/personal-event-live.example.json +94 -0
  175. package/lab/agent-eval/remote-semantic-state-live.example.json +70 -0
  176. package/lab/agent-eval/remote-semantic-state-provider.fixture.json +47 -0
  177. package/lab/agent-eval/remote-state-workspace/AGENTS.md +8 -0
  178. package/lab/agent-eval/remote-state-workspace/opencode.json +7 -0
  179. package/lab/agent-eval/remote-state-workspace/skills/remote-state-operator/SKILL.md +13 -0
  180. package/lab/agent-eval/remote-state.example.json +31 -0
  181. package/lab/agent-eval/workspace/AGENTS.md +7 -0
  182. package/lab/agent-eval/workspace/MEMORY.md +4 -0
  183. package/lab/agent-eval/workspace/artifacts/pending-review.md +3 -0
  184. package/lab/agent-eval/workspace/knowledge/INDEX.md +4 -0
  185. package/lab/agent-eval/workspace/opencode.json +20 -0
  186. package/lab/manifest.example.json +27 -0
  187. package/lab/manifest.personal-event.example.json +27 -0
  188. package/lab/project-workspace/README.md +11 -0
  189. package/lab/project-workspace/fake-multica-provider.mjs +277 -0
  190. package/lab/project-workspace/multica-deploy.fixture.json +29 -0
  191. package/lab/project-workspace/multica-readonly.fixture.json +69 -0
  192. package/lab/project-workspace/observation.fixture.json +14 -0
  193. package/lab/project-workspace/opencode-provider-suite.json +65 -0
  194. package/lab/project-workspace/project.fixture.json +44 -0
  195. package/lab/project-workspace/promotion-policy.fixture.json +15 -0
  196. package/lab/robot-eval/pool.example.json +30 -0
  197. package/lab/robot-eval/suite.json +123 -0
  198. package/lab/robot-eval/workspace/AGENTS.md +21 -0
  199. package/lab/robot-eval/workspace/MEMORY.md +3 -0
  200. package/lab/robot-eval/workspace/knowledge/INDEX.md +5 -0
  201. package/lab/robot-eval/workspace/opencode.json +22 -0
  202. package/lab/schemas/agent-eval-catalog.schema.json +47 -0
  203. package/lab/schemas/lab-manifest.schema.json +70 -0
  204. package/lab/schemas/personal-event-eval.schema.json +91 -0
  205. package/lab/schemas/remote-state-eval.schema.json +66 -0
  206. package/lab/schemas/robot-eval-suite.schema.json +184 -0
  207. package/lab/schemas/robot-pool.schema.json +56 -0
  208. package/package.json +28 -9
  209. package/skills/README.md +23 -0
  210. package/skills/core/dingtalk-agent-compose/SKILL.md +151 -0
  211. package/skills/core/dingtalk-agent-compose/assets/AGENTS.template.md +35 -0
  212. package/skills/core/dingtalk-agent-compose/assets/agent.bindings.dingtalk-doc.template.json +13 -0
  213. package/skills/core/dingtalk-agent-compose/assets/agent.bindings.local.template.json +13 -0
  214. package/skills/core/dingtalk-agent-compose/assets/hosts/opencode/opencode.template.json +12 -0
  215. package/skills/core/dingtalk-agent-compose/assets/role-skill.template.md +32 -0
  216. package/skills/core/dingtalk-agent-compose/evals/evals.json +129 -0
  217. package/skills/core/dingtalk-agent-compose/references/agent-definition-contract.md +55 -0
  218. package/skills/core/dingtalk-agent-compose/references/host-loading-contract.md +58 -0
  219. package/skills/core/dingtalk-agent-compose/references/hosts/claude-code.md +48 -0
  220. package/skills/core/dingtalk-agent-compose/references/hosts/opencode.md +77 -0
  221. package/skills/core/dingtalk-agent-compose/references/storage-routing.md +20 -0
  222. package/skills/core/dingtalk-agent-eval/SKILL.md +140 -0
  223. package/skills/core/dingtalk-agent-eval/assets/eval-catalog.template.json +18 -0
  224. package/skills/core/dingtalk-agent-eval/evals/evals.json +83 -0
  225. package/skills/core/dingtalk-agent-eval/references/eval-topology.md +48 -0
  226. package/skills/core/dingtalk-agent-eval/references/evidence-contract.md +52 -0
  227. package/skills/core/dingtalk-agent-eval/references/failure-to-case.md +35 -0
  228. package/skills/core/dingtalk-agent-eval/references/interactive-debug-channels.md +93 -0
  229. package/skills/core/dingtalk-agent-eval/references/local-connector-smoke.md +75 -0
  230. package/skills/core/dingtalk-agent-eval/references/scenario-taxonomy.md +25 -0
  231. package/skills/core/dingtalk-agent-eval/references/storage-modes.md +75 -0
  232. package/skills/core/dingtalk-basic-behavior/SKILL.md +87 -0
  233. package/skills/core/dingtalk-basic-behavior/assets/memory-candidate-proposal.json +10 -0
  234. package/skills/{dingtalk-basic-behavior/assets/task-checkpoint.md → core/dingtalk-basic-behavior/assets/task-checkpoint.json} +2 -21
  235. package/skills/{dingtalk-basic-behavior → core/dingtalk-basic-behavior}/references/action-contract.md +2 -0
  236. package/skills/core/dingtalk-basic-behavior/references/memory-and-evolution.md +53 -0
  237. package/skills/core/dingtalk-basic-behavior/references/perception-and-gates.md +28 -0
  238. package/skills/core/dingtalk-basic-behavior/references/risk-authority-and-privacy.md +62 -0
  239. package/skills/{dingtalk-basic-behavior → core/dingtalk-basic-behavior}/references/task-lifecycle.md +47 -10
  240. package/skills/core/dingtalk-basic-behavior/references/truth-and-recovery.md +65 -0
  241. package/skills/platforms/deap/PLATFORM.md +3 -0
  242. package/skills/platforms/deap/README.md +3 -0
  243. package/skills/platforms/multica-dingtalk/PLATFORM.md +40 -0
  244. package/skills/platforms/multica-dingtalk/dingtalk-agent-boot-multica/SKILL.md +40 -0
  245. package/skills/platforms/multica-dingtalk/dingtalk-agent-deploy-multica/SKILL.md +60 -0
  246. package/skills/platforms/multica-dingtalk/dingtalk-agent-deploy-multica/references/multica-deployment-contract.md +49 -0
  247. package/skills/platforms/multica-dingtalk/dingtalk-agent-deploy-multica/references/promotion-observation-contract.md +49 -0
  248. package/skills/platforms/multica-dingtalk/multica-external/SKILL.md +282 -0
  249. package/skills/platforms/multica-dingtalk/multica-external/scripts/bootstrap.sh +78 -0
  250. package/skills/platforms/multica-dingtalk/multica-external/scripts/multica_ext.py +1180 -0
  251. package/skills/dingtalk-basic-behavior/SKILL.md +0 -86
  252. package/skills/dingtalk-basic-behavior/references/memory-and-evolution.md +0 -27
  253. /package/skills/{dingtalk-basic-behavior → core/dingtalk-basic-behavior}/references/event-to-behavior.md +0 -0
  254. /package/skills/{dingtalk-basic-behavior → core/dingtalk-basic-behavior}/references/runtime-modes.md +0 -0
@@ -0,0 +1,270 @@
1
+ import { existsSync, lstatSync, readdirSync, realpathSync, statSync, } from 'node:fs';
2
+ import { homedir } from 'node:os';
3
+ import { isAbsolute, join, relative, resolve } from 'node:path';
4
+ export function instructionTargetsPath(workspace, instruction, expected) {
5
+ const raw = instruction.trim();
6
+ if (!raw || !expected.trim())
7
+ return false;
8
+ if (/^https?:\/\//i.test(raw))
9
+ return false;
10
+ const lexicalRoot = resolve(workspace);
11
+ const root = existsSync(lexicalRoot) ? realpathSync(lexicalRoot) : lexicalRoot;
12
+ const target = resolve(root, expected);
13
+ if (instructionUsesGlob(raw)) {
14
+ return globTargetsPath(root, raw, target);
15
+ }
16
+ const expanded = expandHome(raw);
17
+ const candidate = isAbsolute(expanded) ? resolve(expanded) : resolve(root, expanded);
18
+ if (existsSync(candidate) && existsSync(target))
19
+ return sameEntry(candidate, target);
20
+ // For paths that do not exist, only an exact lexical path inside the workspace
21
+ // can be proven equivalent. Existing aliases are compared above across workspace
22
+ // boundaries because OpenCode also accepts absolute and ~/ instructions.
23
+ return isInside(root, candidate) && candidate === target;
24
+ }
25
+ export function instructionUsesGlob(instruction) {
26
+ return /[*?\[\]{}\\]/.test(instruction) || /(?:^!|[@+!]\()/.test(instruction);
27
+ }
28
+ export function countInstructionsForPath(workspace, instructions, expected) {
29
+ return instructions.filter((instruction) => instructionTargetsPath(workspace, instruction, expected)).length;
30
+ }
31
+ function globTargetsPath(root, raw, target) {
32
+ // npm glob/minimatch treats backslash as an escape on POSIX. Avoid treating
33
+ // escaped managed paths as unrelated lexical filenames.
34
+ if (raw.includes('\\'))
35
+ return true;
36
+ let expanded = expandHome(raw).replace(/\\/g, '/');
37
+ // Absolute and home-relative globs can match aliases anywhere on disk. Without
38
+ // traversing an unbounded external tree we cannot prove they exclude a managed
39
+ // instruction, so reject them fail-closed.
40
+ if (raw.startsWith('~/') || isAbsolute(expanded))
41
+ return true;
42
+ // OpenCode/glob accepts cwd-relative `./` forms. Normalize harmless current
43
+ // directory segments before matching; parent traversal is handled fail-closed
44
+ // by compileRelativeGlob because its search boundary is no longer finite.
45
+ expanded = expanded.split('/').filter((segment) => segment !== '.' && segment !== '').join('/');
46
+ const matchers = compileRelativeGlob(expanded);
47
+ if (!matchers)
48
+ return true;
49
+ const targetRelative = slash(relative(root, target));
50
+ if (matchers.some((matcher) => matcher.test(targetRelative)))
51
+ return true;
52
+ if (!existsSync(target))
53
+ return false;
54
+ // A textually unrelated pattern may still load the managed file through a
55
+ // symlink or hardlink. Scan names inside the finite workspace without following
56
+ // directory links and compare every matching entry by realpath/inode.
57
+ const targetReal = realpathSync(target);
58
+ const pending = [root];
59
+ while (pending.length) {
60
+ const directory = pending.pop();
61
+ let entries;
62
+ try {
63
+ entries = readdirSync(directory, { withFileTypes: true });
64
+ }
65
+ catch {
66
+ return true;
67
+ }
68
+ for (const entry of entries) {
69
+ const path = join(directory, entry.name);
70
+ const rel = slash(relative(root, path));
71
+ let info;
72
+ try {
73
+ info = lstatSync(path);
74
+ }
75
+ catch {
76
+ return true;
77
+ }
78
+ if (info.isSymbolicLink()) {
79
+ let linked = '';
80
+ try {
81
+ linked = realpathSync(path);
82
+ }
83
+ catch {
84
+ return true;
85
+ }
86
+ if (matchers.some((matcher) => matcher.test(rel)) && sameEntry(path, target))
87
+ return true;
88
+ try {
89
+ const linkedInfo = statSync(path);
90
+ if (linkedInfo.isDirectory()) {
91
+ // npm glob may traverse a symlink when that directory is named by an
92
+ // explicit pattern segment. Its external descendants are unbounded,
93
+ // so any potentially traversable directory link is fail-closed.
94
+ if (globMayTraverseDirectory(expanded, rel))
95
+ return true;
96
+ if (isInside(linked, targetReal)) {
97
+ const alias = slash(join(rel, relative(linked, targetReal)));
98
+ if (matchers.some((matcher) => matcher.test(alias)))
99
+ return true;
100
+ }
101
+ }
102
+ }
103
+ catch {
104
+ return true;
105
+ }
106
+ continue;
107
+ }
108
+ if (info.isDirectory()) {
109
+ pending.push(path);
110
+ continue;
111
+ }
112
+ if (info.isFile() && matchers.some((matcher) => matcher.test(rel)) &&
113
+ sameEntry(path, target))
114
+ return true;
115
+ }
116
+ }
117
+ return false;
118
+ }
119
+ function globMayTraverseDirectory(pattern, directory) {
120
+ const magic = pattern.search(/[*?\[\]{}()]/);
121
+ const literal = magic < 0 ? pattern : pattern.slice(0, magic);
122
+ const prefix = literal.endsWith('/')
123
+ ? literal.slice(0, -1)
124
+ : literal.includes('/') ? literal.slice(0, literal.lastIndexOf('/')) : '';
125
+ if (!prefix)
126
+ return true;
127
+ return directory === prefix || directory.startsWith(`${prefix}/`) ||
128
+ prefix.startsWith(`${directory}/`);
129
+ }
130
+ function compileRelativeGlob(pattern) {
131
+ // Minimatch supports POSIX/nested character classes (for example
132
+ // `[[:punct:]]`) that the small deterministic compiler below does not.
133
+ // Treat any nested class syntax as unknown and therefore targetable.
134
+ if (/\[[^\]]*\[/.test(pattern))
135
+ return null;
136
+ const expanded = expandSimpleAlternatives(pattern);
137
+ if (!expanded || expanded.length > 64)
138
+ return null;
139
+ if (expanded.some((item) => item.split('/').includes('..')))
140
+ return null;
141
+ const flags = ['darwin', 'win32'].includes(process.platform) ? 'i' : '';
142
+ try {
143
+ return expanded.map((item) => new RegExp(`^${globBody(item)}$`, flags));
144
+ }
145
+ catch {
146
+ return null;
147
+ }
148
+ }
149
+ function expandSimpleAlternatives(pattern) {
150
+ const special = findAlternative(pattern);
151
+ if (!special) {
152
+ // Negation and repetition extglobs need full minimatch semantics; fail closed.
153
+ if (/(?:^!|[?+*!]\()/.test(pattern))
154
+ return null;
155
+ return [pattern];
156
+ }
157
+ const alternatives = splitAlternatives(special.body, special.separator);
158
+ // Only comma alternatives are implemented for braces. Numeric/alphabetic ranges
159
+ // and empty branches have minimatch-specific semantics, so reject them rather
160
+ // than incorrectly proving that they cannot target a managed instruction.
161
+ if (!alternatives.length || alternatives.some((item) => item.length === 0) ||
162
+ (special.separator === ',' && alternatives.length < 2))
163
+ return null;
164
+ const results = [];
165
+ for (const alternative of alternatives) {
166
+ const nested = expandSimpleAlternatives(pattern.slice(0, special.start) + alternative + pattern.slice(special.end + 1));
167
+ if (!nested)
168
+ return null;
169
+ results.push(...nested);
170
+ }
171
+ return results;
172
+ }
173
+ function findAlternative(pattern) {
174
+ for (let index = 0; index < pattern.length; index++) {
175
+ const char = pattern[index];
176
+ const extglob = char === '@' && pattern[index + 1] === '(';
177
+ if (char !== '{' && !extglob)
178
+ continue;
179
+ const open = extglob ? '(' : '{';
180
+ const close = extglob ? ')' : '}';
181
+ const bodyStart = index + (extglob ? 2 : 1);
182
+ let depth = 1;
183
+ for (let cursor = bodyStart; cursor < pattern.length; cursor++) {
184
+ if (pattern[cursor] === open)
185
+ depth++;
186
+ else if (pattern[cursor] === close && --depth === 0) {
187
+ return {
188
+ start: index, end: cursor, body: pattern.slice(bodyStart, cursor),
189
+ separator: extglob ? '|' : ',',
190
+ };
191
+ }
192
+ }
193
+ return null;
194
+ }
195
+ return null;
196
+ }
197
+ function splitAlternatives(body, separator) {
198
+ const values = [];
199
+ let start = 0;
200
+ let depth = 0;
201
+ for (let index = 0; index < body.length; index++) {
202
+ if ('({['.includes(body[index]))
203
+ depth++;
204
+ else if (')}]'.includes(body[index]))
205
+ depth--;
206
+ else if (body[index] === separator && depth === 0) {
207
+ values.push(body.slice(start, index));
208
+ start = index + 1;
209
+ }
210
+ }
211
+ values.push(body.slice(start));
212
+ return values;
213
+ }
214
+ function globBody(pattern) {
215
+ let result = '';
216
+ for (let index = 0; index < pattern.length; index++) {
217
+ const char = pattern[index];
218
+ if (char === '*') {
219
+ if (pattern[index + 1] === '*') {
220
+ index++;
221
+ if (pattern[index + 1] === '/') {
222
+ index++;
223
+ result += '(?:.*/)?';
224
+ }
225
+ else
226
+ result += '.*';
227
+ }
228
+ else
229
+ result += '[^/]*';
230
+ }
231
+ else if (char === '?')
232
+ result += '[^/]';
233
+ else if (char === '[') {
234
+ const end = pattern.indexOf(']', index + 1);
235
+ if (end < 0)
236
+ throw new Error('unterminated character class');
237
+ const body = pattern.slice(index + 1, end);
238
+ result += `[${body.startsWith('!') ? '^' + body.slice(1) : body}]`;
239
+ index = end;
240
+ }
241
+ else {
242
+ result += char.replace(/[|\\{}()[\]^$+?.]/g, '\\$&');
243
+ }
244
+ }
245
+ return result;
246
+ }
247
+ function expandHome(path) {
248
+ return path.startsWith('~/') ? join(homedir(), path.slice(2)) : path;
249
+ }
250
+ function sameEntry(left, right) {
251
+ try {
252
+ if (realpathSync(left) === realpathSync(right))
253
+ return true;
254
+ const leftStat = statSync(left);
255
+ const rightStat = statSync(right);
256
+ return leftStat.dev === rightStat.dev && leftStat.ino === rightStat.ino;
257
+ }
258
+ catch {
259
+ return false;
260
+ }
261
+ }
262
+ function slash(value) {
263
+ return value.replace(/\\/g, '/');
264
+ }
265
+ function isInside(root, candidate) {
266
+ const rel = relative(root, candidate);
267
+ const separator = process.platform === 'win32' ? '\\' : '/';
268
+ return rel === '' || (rel !== '..' && !rel.startsWith(`..${separator}`));
269
+ }
270
+ //# sourceMappingURL=instruction-path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instruction-path.js","sourceRoot":"","sources":["../../src/instruction-path.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n existsSync, lstatSync, readdirSync, realpathSync, statSync,\n} from 'node:fs'\nimport type { Dirent } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { isAbsolute, join, relative, resolve } from 'node:path'\n\nexport function instructionTargetsPath(\n workspace: string, instruction: string, expected: string,\n): boolean {\n const raw = instruction.trim()\n if (!raw || !expected.trim()) return false\n if (/^https?:\\/\\//i.test(raw)) return false\n const lexicalRoot = resolve(workspace)\n const root = existsSync(lexicalRoot) ? realpathSync(lexicalRoot) : lexicalRoot\n const target = resolve(root, expected)\n\n if (instructionUsesGlob(raw)) {\n return globTargetsPath(root, raw, target)\n }\n\n const expanded = expandHome(raw)\n const candidate = isAbsolute(expanded) ? resolve(expanded) : resolve(root, expanded)\n if (existsSync(candidate) && existsSync(target)) return sameEntry(candidate, target)\n\n // For paths that do not exist, only an exact lexical path inside the workspace\n // can be proven equivalent. Existing aliases are compared above across workspace\n // boundaries because OpenCode also accepts absolute and ~/ instructions.\n return isInside(root, candidate) && candidate === target\n}\n\nexport function instructionUsesGlob(instruction: string): boolean {\n return /[*?\\[\\]{}\\\\]/.test(instruction) || /(?:^!|[@+!]\\()/.test(instruction)\n}\n\nexport function countInstructionsForPath(\n workspace: string, instructions: string[], expected: string,\n): number {\n return instructions.filter((instruction) =>\n instructionTargetsPath(workspace, instruction, expected)).length\n}\n\nfunction globTargetsPath(root: string, raw: string, target: string): boolean {\n // npm glob/minimatch treats backslash as an escape on POSIX. Avoid treating\n // escaped managed paths as unrelated lexical filenames.\n if (raw.includes('\\\\')) return true\n let expanded = expandHome(raw).replace(/\\\\/g, '/')\n // Absolute and home-relative globs can match aliases anywhere on disk. Without\n // traversing an unbounded external tree we cannot prove they exclude a managed\n // instruction, so reject them fail-closed.\n if (raw.startsWith('~/') || isAbsolute(expanded)) return true\n // OpenCode/glob accepts cwd-relative `./` forms. Normalize harmless current\n // directory segments before matching; parent traversal is handled fail-closed\n // by compileRelativeGlob because its search boundary is no longer finite.\n expanded = expanded.split('/').filter((segment) => segment !== '.' && segment !== '').join('/')\n const matchers = compileRelativeGlob(expanded)\n if (!matchers) return true\n const targetRelative = slash(relative(root, target))\n if (matchers.some((matcher) => matcher.test(targetRelative))) return true\n if (!existsSync(target)) return false\n\n // A textually unrelated pattern may still load the managed file through a\n // symlink or hardlink. Scan names inside the finite workspace without following\n // directory links and compare every matching entry by realpath/inode.\n const targetReal = realpathSync(target)\n const pending = [root]\n while (pending.length) {\n const directory = pending.pop()!\n let entries: Dirent[]\n try { entries = readdirSync(directory, { withFileTypes: true }) }\n catch { return true }\n for (const entry of entries) {\n const path = join(directory, entry.name)\n const rel = slash(relative(root, path))\n let info: ReturnType<typeof lstatSync>\n try { info = lstatSync(path) } catch { return true }\n if (info.isSymbolicLink()) {\n let linked = ''\n try { linked = realpathSync(path) } catch { return true }\n if (matchers.some((matcher) => matcher.test(rel)) && sameEntry(path, target)) return true\n try {\n const linkedInfo = statSync(path)\n if (linkedInfo.isDirectory()) {\n // npm glob may traverse a symlink when that directory is named by an\n // explicit pattern segment. Its external descendants are unbounded,\n // so any potentially traversable directory link is fail-closed.\n if (globMayTraverseDirectory(expanded, rel)) return true\n if (isInside(linked, targetReal)) {\n const alias = slash(join(rel, relative(linked, targetReal)))\n if (matchers.some((matcher) => matcher.test(alias))) return true\n }\n }\n } catch { return true }\n continue\n }\n if (info.isDirectory()) {\n pending.push(path)\n continue\n }\n if (info.isFile() && matchers.some((matcher) => matcher.test(rel)) &&\n sameEntry(path, target)) return true\n }\n }\n return false\n}\n\nfunction globMayTraverseDirectory(pattern: string, directory: string): boolean {\n const magic = pattern.search(/[*?\\[\\]{}()]/)\n const literal = magic < 0 ? pattern : pattern.slice(0, magic)\n const prefix = literal.endsWith('/')\n ? literal.slice(0, -1)\n : literal.includes('/') ? literal.slice(0, literal.lastIndexOf('/')) : ''\n if (!prefix) return true\n return directory === prefix || directory.startsWith(`${prefix}/`) ||\n prefix.startsWith(`${directory}/`)\n}\n\nfunction compileRelativeGlob(pattern: string): RegExp[] | null {\n // Minimatch supports POSIX/nested character classes (for example\n // `[[:punct:]]`) that the small deterministic compiler below does not.\n // Treat any nested class syntax as unknown and therefore targetable.\n if (/\\[[^\\]]*\\[/.test(pattern)) return null\n const expanded = expandSimpleAlternatives(pattern)\n if (!expanded || expanded.length > 64) return null\n if (expanded.some((item) => item.split('/').includes('..'))) return null\n const flags = ['darwin', 'win32'].includes(process.platform) ? 'i' : ''\n try { return expanded.map((item) => new RegExp(`^${globBody(item)}$`, flags)) }\n catch { return null }\n}\n\nfunction expandSimpleAlternatives(pattern: string): string[] | null {\n const special = findAlternative(pattern)\n if (!special) {\n // Negation and repetition extglobs need full minimatch semantics; fail closed.\n if (/(?:^!|[?+*!]\\()/.test(pattern)) return null\n return [pattern]\n }\n const alternatives = splitAlternatives(special.body, special.separator)\n // Only comma alternatives are implemented for braces. Numeric/alphabetic ranges\n // and empty branches have minimatch-specific semantics, so reject them rather\n // than incorrectly proving that they cannot target a managed instruction.\n if (!alternatives.length || alternatives.some((item) => item.length === 0) ||\n (special.separator === ',' && alternatives.length < 2)) return null\n const results: string[] = []\n for (const alternative of alternatives) {\n const nested = expandSimpleAlternatives(\n pattern.slice(0, special.start) + alternative + pattern.slice(special.end + 1))\n if (!nested) return null\n results.push(...nested)\n }\n return results\n}\n\nfunction findAlternative(pattern: string): {\n start: number; end: number; body: string; separator: ',' | '|'\n} | null {\n for (let index = 0; index < pattern.length; index++) {\n const char = pattern[index]\n const extglob = char === '@' && pattern[index + 1] === '('\n if (char !== '{' && !extglob) continue\n const open = extglob ? '(' : '{'\n const close = extglob ? ')' : '}'\n const bodyStart = index + (extglob ? 2 : 1)\n let depth = 1\n for (let cursor = bodyStart; cursor < pattern.length; cursor++) {\n if (pattern[cursor] === open) depth++\n else if (pattern[cursor] === close && --depth === 0) {\n return {\n start: index, end: cursor, body: pattern.slice(bodyStart, cursor),\n separator: extglob ? '|' : ',',\n }\n }\n }\n return null\n }\n return null\n}\n\nfunction splitAlternatives(body: string, separator: ',' | '|'): string[] {\n const values: string[] = []\n let start = 0\n let depth = 0\n for (let index = 0; index < body.length; index++) {\n if ('({['.includes(body[index])) depth++\n else if (')}]'.includes(body[index])) depth--\n else if (body[index] === separator && depth === 0) {\n values.push(body.slice(start, index))\n start = index + 1\n }\n }\n values.push(body.slice(start))\n return values\n}\n\nfunction globBody(pattern: string): string {\n let result = ''\n for (let index = 0; index < pattern.length; index++) {\n const char = pattern[index]\n if (char === '*') {\n if (pattern[index + 1] === '*') {\n index++\n if (pattern[index + 1] === '/') {\n index++\n result += '(?:.*/)?'\n } else result += '.*'\n } else result += '[^/]*'\n } else if (char === '?') result += '[^/]'\n else if (char === '[') {\n const end = pattern.indexOf(']', index + 1)\n if (end < 0) throw new Error('unterminated character class')\n const body = pattern.slice(index + 1, end)\n result += `[${body.startsWith('!') ? '^' + body.slice(1) : body}]`\n index = end\n } else {\n result += char.replace(/[|\\\\{}()[\\]^$+?.]/g, '\\\\$&')\n }\n }\n return result\n}\n\nfunction expandHome(path: string): string {\n return path.startsWith('~/') ? join(homedir(), path.slice(2)) : path\n}\n\nfunction sameEntry(left: string, right: string): boolean {\n try {\n if (realpathSync(left) === realpathSync(right)) return true\n const leftStat = statSync(left)\n const rightStat = statSync(right)\n return leftStat.dev === rightStat.dev && leftStat.ino === rightStat.ino\n } catch { return false }\n}\n\nfunction slash(value: string): string {\n return value.replace(/\\\\/g, '/')\n}\n\nfunction isInside(root: string, candidate: string): boolean {\n const rel = relative(root, candidate)\n const separator = process.platform === 'win32' ? '\\\\' : '/'\n return rel === '' || (rel !== '..' && !rel.startsWith(`..${separator}`))\n}\n"]}
@@ -0,0 +1,36 @@
1
+ export function directInvocation(sessionKey = '') {
2
+ return {
3
+ $schema: 'dingtalk-agent/invocation@1',
4
+ mode: 'direct',
5
+ authority: 'default',
6
+ eventId: '',
7
+ sessionKey,
8
+ occurredAt: null,
9
+ actor: null,
10
+ target: null,
11
+ conversation: null,
12
+ };
13
+ }
14
+ export function eventInvocation(event, resume = { mode: 'start' }, sessionKey = '', continued = false) {
15
+ return {
16
+ $schema: 'dingtalk-agent/invocation@1',
17
+ mode: resume.mode === 'start' && !continued ? eventMode(event.kind) : 'continuation',
18
+ authority: 'event',
19
+ eventId: event.id,
20
+ sessionKey,
21
+ occurredAt: event.occurredAt,
22
+ actor: event.actor,
23
+ target: event.replyTarget,
24
+ conversation: event.conversation,
25
+ };
26
+ }
27
+ function eventMode(kind) {
28
+ if (kind === 'im.message.mentioned')
29
+ return 'mention';
30
+ if (kind === 'im.message.dm')
31
+ return 'dm';
32
+ if (kind === 'agent.heartbeat')
33
+ return 'heartbeat';
34
+ return 'ambient';
35
+ }
36
+ //# sourceMappingURL=invocation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invocation.js","sourceRoot":"","sources":["../../src/invocation.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,gBAAgB,CAAC,UAAU,GAAG,EAAE;IAC9C,OAAO;QACL,OAAO,EAAE,6BAA6B;QACtC,IAAI,EAAE,QAAQ;QACd,SAAS,EAAE,SAAS;QACpB,OAAO,EAAE,EAAE;QACX,UAAU;QACV,UAAU,EAAE,IAAI;QAChB,KAAK,EAAE,IAAI;QACX,MAAM,EAAE,IAAI;QACZ,YAAY,EAAE,IAAI;KACnB,CAAA;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,KAAsB,EACtB,SAAwB,EAAE,IAAI,EAAE,OAAO,EAAE,EACzC,UAAU,GAAG,EAAE,EACf,SAAS,GAAG,KAAK;IAEjB,OAAO;QACL,OAAO,EAAE,6BAA6B;QACtC,IAAI,EAAE,MAAM,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,cAAc;QACpF,SAAS,EAAE,OAAO;QAClB,OAAO,EAAE,KAAK,CAAC,EAAE;QACjB,UAAU;QACV,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,MAAM,EAAE,KAAK,CAAC,WAAW;QACzB,YAAY,EAAE,KAAK,CAAC,YAAY;KACjC,CAAA;AACH,CAAC;AAED,SAAS,SAAS,CAAC,IAAY;IAC7B,IAAI,IAAI,KAAK,sBAAsB;QAAE,OAAO,SAAS,CAAA;IACrD,IAAI,IAAI,KAAK,eAAe;QAAE,OAAO,IAAI,CAAA;IACzC,IAAI,IAAI,KAAK,iBAAiB;QAAE,OAAO,WAAW,CAAA;IAClD,OAAO,SAAS,CAAA;AAClB,CAAC","sourcesContent":["import type {\n InvocationContext, InvocationMode, NormalizedEvent, ResumeContext,\n} from './types.js'\n\nexport function directInvocation(sessionKey = ''): InvocationContext {\n return {\n $schema: 'dingtalk-agent/invocation@1',\n mode: 'direct',\n authority: 'default',\n eventId: '',\n sessionKey,\n occurredAt: null,\n actor: null,\n target: null,\n conversation: null,\n }\n}\n\nexport function eventInvocation(\n event: NormalizedEvent,\n resume: ResumeContext = { mode: 'start' },\n sessionKey = '',\n continued = false,\n): InvocationContext {\n return {\n $schema: 'dingtalk-agent/invocation@1',\n mode: resume.mode === 'start' && !continued ? eventMode(event.kind) : 'continuation',\n authority: 'event',\n eventId: event.id,\n sessionKey,\n occurredAt: event.occurredAt,\n actor: event.actor,\n target: event.replyTarget,\n conversation: event.conversation,\n }\n}\n\nfunction eventMode(kind: string): InvocationMode {\n if (kind === 'im.message.mentioned') return 'mention'\n if (kind === 'im.message.dm') return 'dm'\n if (kind === 'agent.heartbeat') return 'heartbeat'\n return 'ambient'\n}\n"]}