@xdxer/dingtalk-agent 0.1.4-beta.16 → 0.1.4-beta.17
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 +23 -0
- package/README.en.md +1 -0
- package/README.md +1 -0
- package/dist/bin/dingtalk-agent.js +15 -8
- package/dist/bin/dingtalk-agent.js.map +1 -1
- package/dist/src/agent-audit.js +12 -5
- package/dist/src/agent-audit.js.map +1 -1
- package/dist/src/development-workspace.js +17 -3
- package/dist/src/development-workspace.js.map +1 -1
- package/dist/src/doctor.js +41 -6
- package/dist/src/doctor.js.map +1 -1
- package/dist/src/map.js +157 -0
- package/dist/src/map.js.map +1 -0
- package/dist/src/multica-deploy.js +76 -19
- package/dist/src/multica-deploy.js.map +1 -1
- package/dist/src/multica-provider.js +1 -1
- package/dist/src/multica-provider.js.map +1 -1
- package/dist/src/skill-manager.js +98 -10
- package/dist/src/skill-manager.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/docs/schemas/project.schema.json +1 -0
- package/lab/agent-eval/catalog.json +5 -5
- package/lab/agent-eval/classic-failures.json +2 -2
- package/lab/project-workspace/fake-multica-provider.mjs +17 -6
- package/lab/project-workspace/opencode-provider-suite.json +1 -1
- package/lab/schemas/agent-eval-catalog.schema.json +1 -1
- package/package.json +3 -2
- package/skills/core/dingtalk-agent-compose/SKILL.md +6 -3
- package/skills/core/dingtalk-agent-compose/evals/evals.json +11 -0
- package/skills/core/dingtalk-agent-eval/SKILL.md +16 -4
- package/skills/core/dingtalk-agent-eval/assets/eval-catalog.template.json +1 -1
- package/skills/core/dingtalk-agent-eval/evals/evals.json +22 -0
- package/skills/core/dingtalk-agent-eval/references/eval-topology.md +2 -0
- package/skills/core/dingtalk-agent-eval/references/evidence-contract.md +4 -0
- package/skills/core/dingtalk-agent-eval/references/interactive-debug-channels.md +93 -0
- package/skills/platforms/multica-dingtalk/PLATFORM.md +4 -2
- package/skills/platforms/multica-dingtalk/dingtalk-agent-boot-multica/SKILL.md +4 -4
- package/skills/platforms/multica-dingtalk/multica-external/SKILL.md +2 -0
package/dist/src/doctor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACzE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAE9C,OAAO,EACL,iBAAiB,EAAE,gBAAgB,GACpC,MAAM,oBAAoB,CAAA;AA0B3B,MAAM,UAAU,MAAM,CAAC,WAAmB,EAAE,UAAyB,EAAE;IACrE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,EAAE,CAAA;IACtC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAA;IACtC,MAAM,MAAM,GAAkB,EAAE,CAAA;IAChC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAC,CAAA;IAC/E,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,CAAA;IAEzC,MAAM,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAA;IACzC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,WAAW,EAAE,QAAQ,CAAC;QAC/C,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,WAAW,EAAE,EAAE;QAClE,CAAC,CAAC;YACE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,WAAW,KAAK;YAC/D,GAAG,EAAE,wBAAwB;SAC9B,CAAC,CAAA;IAEN,MAAM,GAAG,GAAG,cAAc,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAA;IACjD,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;IACxC,IAAI,GAAG,IAAI,KAAK,EAAE,CAAC;QACjB,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,EAAE,GAAG,CAAC,CAAA;QAClD,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,WAAW,CAAC,EAAE,GAAG,CAAC,CAAA;QACnD,MAAM,gBAAgB,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QACxE,MAAM,YAAY,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QAClE,MAAM,CAAC,IAAI,CAAC,gBAAgB,KAAK,OAAO,IAAI,YAAY,KAAK,OAAO;YAClE,CAAC,CAAC;gBACE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,gBAAgB,oBAAoB;gBAC9E,MAAM,EAAE,GAAG,GAAG,MAAM,KAAK,EAAE;aAC5B;YACH,CAAC,CAAC;gBACE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,uBAAuB;gBAC1D,MAAM,EAAE,GAAG,GAAG,KAAK,gBAAgB,IAAI,QAAQ,OAAO,KAAK,KAAK,YAAY,IAAI,QAAQ,GAAG;gBAC3F,GAAG,EAAE,4EAA4E,OAAO,QAAQ;aACjG,CAAC,CAAA;IACR,CAAC;SAAM,IAAI,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,MAAM,CAAC,IAAI,CAAC;YACV,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,sCAAsC;YACzE,MAAM,EAAE,kBAAkB,GAAG,IAAI,SAAS,UAAU,KAAK,IAAI,SAAS,EAAE;YACxE,GAAG,EAAE,4EAA4E,OAAO,QAAQ;SACjG,CAAC,CAAA;IACJ,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,IAAI,CAAC;YACR,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,yBAAyB;YAC5D,MAAM,EAAE,WAAW,GAAG,CAAC,IAAI,IAAI,EAAE,EAAE;YACnC,GAAG,EAAE,4EAA4E,OAAO,QAAQ;SACjG,CAAC,CAAA;IACN,CAAC;IAED,MAAM,GAAG,GAAG,cAAc,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;IACtC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,CAAC,IAAI,CAAC;YACV,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc;YACjD,GAAG,EAAE,6CAA6C;SACnD,CAAC,CAAA;QACF,MAAM,CAAC,IAAI,CAAC;YACV,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa;YACrD,GAAG,EAAE,4BAA4B;SAClC,CAAC,CAAA;IACJ,CAAC;SAAM,CAAC;QACN,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,GAAG,CAAC,CAAA;QACrE,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,EAAE,OAAO,IAAI,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;QAC3E,MAAM,SAAS,GAAG,UAAU,CAAC,EAAE,IAAI,cAAc,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAA;QACvG,MAAM,CAAC,IAAI,CAAC,SAAS;YACnB,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,UAAU,IAAI,KAAK,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE;YAClF,CAAC,CAAC;gBACE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM;gBACxB,OAAO,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,UAAU,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,aAAa;gBAChF,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK;gBAC9C,GAAG,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,sBAAsB;aACjE,CAAC,CAAA;QAEN,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,GAAG,CAAC,CAAA;QACzE,MAAM,aAAa,GAAG,OAAO,CAAC,EAAE,IAAI,OAAO,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI;YACtE,OAAO,CAAC,IAAI,EAAE,WAAW,KAAK,KAAK,CAAA;QACrC,MAAM,CAAC,IAAI,CAAC,aAAa;YACvB,CAAC,CAAC;gBACE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS;gBACjD,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;aACvF;YACH,CAAC,CAAC;gBACE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB;gBACxD,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,qBAAqB,EAAE,GAAG,EAAE,qBAAqB;aAC3E,CAAC,CAAA;IACR,CAAC;IAED,MAAM,KAAK,GAAG,gBAAgB,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;IACrD,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,iBAAiB,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;IAC7F,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;IACvE,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;IACtE,MAAM,gBAAgB,GAAG,KAAK,CAAC,MAAM;SAClC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACzE,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM;SAC9B,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;SACzC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC1F,MAAM,CAAC,IAAI,CAAC,UAAU;QACpB,CAAC,CAAC;YACE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM;YAC1B,OAAO,EAAE,iBAAiB,gBAAgB,EAAE;YAC5C,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;SACpE;QACH,CAAC,CAAC;YACE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;YAChD,OAAO,EAAE,iBAAiB,YAAY,EAAE;YACxC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;YACnE,GAAG,EAAE,UAAU;gBACb,CAAC,CAAC,mCAAmC;gBACrC,CAAC,CAAC,uEAAuE;SAC5E,CAAC,CAAA;IAEN,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACzC,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,IAAI,SAAS;SACpF,CAAC,CAAC,CAAA;QACH,MAAM,KAAK,GAAe,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,KAAK,UAAU,CAAC;YACxE,CAAC,CAAC,MAAM;YACR,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAA;QACrE,MAAM,CAAC,IAAI,CAAC;YACV,EAAE,EAAE,MAAM,CAAC,IAAI;YACf,KAAK;YACL,OAAO,EAAE,GAAG,MAAM,CAAC,KAAK,KAAK,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,iBAAiB,EAAE;YACrH,MAAM,EAAE,GAAG,MAAM,CAAC,SAAS,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YAChG,GAAG,EAAE,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,mCAAmC;SACxE,CAAC,CAAA;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,MAAM;SACrB,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC;SACtD,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAa,CAAC;SACnC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,CAAA;IAC5D,OAAO;QACL,OAAO,EAAE,yBAAyB;QAClC,KAAK,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,MAAM,CAAC;QACtD,MAAM;QACN,SAAS;QACT,KAAK;QACL,MAAM,EAAE,KAAK,CAAC,MAAM;KACrB,CAAA;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAAe,EAAE,MAAyB,OAAO,CAAC,GAAG;IAClF,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,IAAI,EAAE,CAAA;IAC3B,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO;QAC7C,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,IAAI,gBAAgB,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;QAC9C,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;IACR,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9D,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,EAAE,OAAO,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC,CAAA;YACvE,IAAI,CAAC;gBACH,UAAU,CAAC,SAAS,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;gBACrF,OAAO,SAAS,CAAA;YAClB,CAAC;YAAC,MAAM,CAAC,CAAC,cAAc,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IACD,OAAO,EAAE,CAAA;AACX,CAAC;AAED,SAAS,OAAO,CAAC,OAAe,EAAE,IAAc,EAAE,GAAsB;IACtE,MAAM,GAAG,GAAG,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAA;IAC/E,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;IAC9C,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;IAC9C,IAAI,IAAI,GAAQ,IAAI,CAAA;IACpB,IAAI,CAAC;QAAC,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,6BAA6B,CAAC,CAAC;IACzF,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK;QAClC,IAAI;QACJ,MAAM;QACN,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,OAAO,IAAI,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,MAAM,EAAE,CAAC;KACjG,CAAA;AACH,CAAC;AAED,SAAS,OAAO,CAAC,OAAe,EAAE,IAAc,EAAE,GAAsB;IACtE,MAAM,GAAG,GAAG,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAA;IAC/E,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK;QAClC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;KACxC,CAAA;AACH,CAAC;AAED,SAAS,SAAS,CAAC,IAAY;IAC7B,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA;AAChD,CAAC;AAED,SAAS,cAAc,CAAC,MAAc,EAAE,OAAe;IACrD,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;IACzE,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;IAC1E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACzD,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAAE,OAAO,IAAI,CAAA;QAC1C,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAAE,OAAO,KAAK,CAAA;IAC7C,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC","sourcesContent":["import { accessSync, constants, existsSync, readFileSync } from 'node:fs'\nimport { delimiter, dirname, join, resolve } from 'node:path'\nimport { homedir } from 'node:os'\nimport { spawnSync } from 'node:child_process'\n\nimport {\n GLOBAL_SKILL_NAME, skillSuiteStatus, type GlobalSkillStatus,\n} from './skill-manager.js'\n\nexport type CheckLevel = 'pass' | 'warn' | 'fail'\n\nexport interface DoctorCheck {\n id: 'node' | 'cli' | 'dws' | 'dws-auth' | 'skill' | 'claude-code' | 'codex' | 'opencode'\n level: CheckLevel\n summary: string\n detail?: string\n fix?: string\n}\n\nexport interface DoctorReport {\n $schema: 'dingtalk-agent/doctor@1'\n ready: boolean\n checks: DoctorCheck[]\n nextSteps: string[]\n skill: GlobalSkillStatus\n skills: GlobalSkillStatus[]\n}\n\nexport interface DoctorOptions {\n home?: string\n env?: NodeJS.ProcessEnv\n}\n\nexport function doctor(packageRoot: string, options: DoctorOptions = {}): DoctorReport {\n const home = options.home || homedir()\n const env = options.env || process.env\n const checks: DoctorCheck[] = []\n const pkg = JSON.parse(readFileSync(join(packageRoot, 'package.json'), 'utf8'))\n const version = String(pkg.version || '')\n\n const nodeVersion = process.versions.node\n checks.push(versionAtLeast(nodeVersion, '18.3.0')\n ? { id: 'node', level: 'pass', summary: `Node.js ${nodeVersion}` }\n : {\n id: 'node', level: 'fail', summary: `Node.js ${nodeVersion} 过旧`,\n fix: '升级到 Node.js 18.3 或更高版本',\n })\n\n const cli = findExecutable('dingtalk-agent', env)\n const alias = findExecutable('dta', env)\n if (cli && alias) {\n const installed = runText(cli, ['--version'], env)\n const aliasRun = runText(alias, ['--version'], env)\n const installedVersion = installed.ok ? firstLine(installed.stdout) : ''\n const aliasVersion = aliasRun.ok ? firstLine(aliasRun.stdout) : ''\n checks.push(installedVersion === version && aliasVersion === version\n ? {\n id: 'cli', level: 'pass', summary: `CLI ${installedVersion} 已在 PATH 中(dta 可用)`,\n detail: `${cli} · ${alias}`,\n }\n : {\n id: 'cli', level: 'warn', summary: 'PATH 中的 CLI 版本与当前包不一致',\n detail: `${cli} (${installedVersion || '无法识别版本'}) · ${alias} (${aliasVersion || '无法识别版本'})`,\n fix: `运行 npx --yes --registry=https://registry.npmjs.org @xdxer/dingtalk-agent@${version} setup`,\n })\n } else if (cli || alias) {\n checks.push({\n id: 'cli', level: 'fail', summary: 'CLI 入口不完整:dingtalk-agent 与 dta 应同时存在',\n detail: `dingtalk-agent=${cli || 'missing'} · dta=${alias || 'missing'}`,\n fix: `运行 npx --yes --registry=https://registry.npmjs.org @xdxer/dingtalk-agent@${version} setup`,\n })\n } else {\n checks.push({\n id: 'cli', level: 'fail', summary: 'PATH 找不到 dingtalk-agent',\n detail: `当前 PATH=${env.PATH || ''}`,\n fix: `运行 npx --yes --registry=https://registry.npmjs.org @xdxer/dingtalk-agent@${version} setup`,\n })\n }\n\n const dws = findExecutable('dws', env)\n if (!dws) {\n checks.push({\n id: 'dws', level: 'fail', summary: 'PATH 找不到 dws',\n fix: '安装 DWS,并确认 `dws version --format json` 可以执行',\n })\n checks.push({\n id: 'dws-auth', level: 'fail', summary: '无法检查 DWS 认证',\n fix: 'DWS 可用后运行 `dws auth login`',\n })\n } else {\n const versionRun = runJson(dws, ['version', '--format', 'json'], env)\n const dwsVersion = versionRun.json?.version || firstLine(versionRun.stdout)\n const supported = versionRun.ok && versionAtLeast(String(dwsVersion || '').replace(/^v/, ''), '1.0.15')\n checks.push(supported\n ? { id: 'dws', level: 'pass', summary: `DWS ${dwsVersion || '可执行'}`, detail: dws }\n : {\n id: 'dws', level: 'fail',\n summary: versionRun.ok ? `DWS ${dwsVersion || ''} 低于最低版本 1.0.15` : 'DWS 存在但无法运行',\n detail: versionRun.ok ? dws : versionRun.error,\n fix: versionRun.ok ? '运行 `dws upgrade`' : '运行 `dws doctor` 检查安装',\n })\n\n const authRun = runJson(dws, ['auth', 'status', '--format', 'json'], env)\n const authenticated = authRun.ok && authRun.json?.authenticated === true &&\n authRun.json?.token_valid !== false\n checks.push(authenticated\n ? {\n id: 'dws-auth', level: 'pass', summary: 'DWS 已认证',\n detail: [authRun.json?.corp_name, authRun.json?.user_name].filter(Boolean).join(' · '),\n }\n : {\n id: 'dws-auth', level: 'fail', summary: 'DWS 尚未认证或凭据已失效',\n detail: authRun.error || 'authenticated=false', fix: '运行 `dws auth login`',\n })\n }\n\n const suite = skillSuiteStatus(packageRoot, { home })\n const skill = suite.skills.find((item) => item.name === GLOBAL_SKILL_NAME) || suite.skills[0]\n const allCurrent = suite.skills.every((item) => item.canonical.current)\n const anyMissing = suite.skills.some((item) => !item.canonical.exists)\n const installedSummary = suite.skills\n .map((item) => `${item.name} ${item.bundled.skillVersion}`).join(' + ')\n const staleSummary = suite.skills\n .filter((item) => !item.canonical.current)\n .map((item) => `${item.name}=${item.canonical.exists ? '需升级或有本地修改' : '未安装'}`).join('; ')\n checks.push(allCurrent\n ? {\n id: 'skill', level: 'pass',\n summary: `内置 Skill 已安装: ${installedSummary}`,\n detail: suite.skills.map((item) => item.canonical.path).join(' · '),\n }\n : {\n id: 'skill', level: anyMissing ? 'fail' : 'warn',\n summary: `内置 Skill 不完整: ${staleSummary}`,\n detail: suite.skills.map((item) => item.canonical.path).join(' · '),\n fix: anyMissing\n ? '运行 `dingtalk-agent skill install`'\n : '运行 `dingtalk-agent skill status`,确认后执行 `dingtalk-agent skill upgrade`',\n })\n\n for (const client of skill.clients) {\n const states = suite.skills.map((item) => ({\n name: item.name,\n state: item.clients.find((entry) => entry.name === client.name)?.state || 'missing',\n }))\n const level: CheckLevel = states.some((item) => item.state === 'conflict')\n ? 'fail'\n : states.some((item) => item.state === 'missing') ? 'warn' : 'pass'\n checks.push({\n id: client.name,\n level,\n summary: `${client.label}: ${level === 'pass' ? '可发现内置 Skill' : level === 'fail' ? 'Skill 路径冲突' : '尚不可发现全部内置 Skill'}`,\n detail: `${client.discovery} · ${states.map((item) => `${item.name}=${item.state}`).join('; ')}`,\n fix: level === 'pass' ? undefined : '运行 `dingtalk-agent skill install`',\n })\n }\n\n const nextSteps = checks\n .filter((check) => check.level !== 'pass' && check.fix)\n .map((check) => check.fix as string)\n .filter((step, index, all) => all.indexOf(step) === index)\n return {\n $schema: 'dingtalk-agent/doctor@1',\n ready: !checks.some((check) => check.level === 'fail'),\n checks,\n nextSteps,\n skill,\n skills: suite.skills,\n }\n}\n\nexport function findExecutable(command: string, env: NodeJS.ProcessEnv = process.env): string {\n const path = env.PATH || ''\n const extensions = process.platform === 'win32'\n ? (env.PATHEXT || '.EXE;.CMD;.BAT').split(';')\n : ['']\n for (const directory of path.split(delimiter).filter(Boolean)) {\n for (const extension of extensions) {\n const candidate = resolve(directory, command + extension.toLowerCase())\n try {\n accessSync(candidate, process.platform === 'win32' ? constants.F_OK : constants.X_OK)\n return candidate\n } catch { /* continue */ }\n }\n }\n return ''\n}\n\nfunction runJson(command: string, args: string[], env: NodeJS.ProcessEnv) {\n const run = spawnSync(command, args, { encoding: 'utf8', env, timeout: 8_000 })\n const stdout = String(run.stdout || '').trim()\n const stderr = String(run.stderr || '').trim()\n let json: any = null\n try { json = stdout ? JSON.parse(stdout) : null } catch { /* human output is allowed */ }\n return {\n ok: run.status === 0 && !run.error,\n json,\n stdout,\n error: run.error?.message || stderr || (run.signal ? `被 ${run.signal} 终止` : `退出码 ${run.status}`),\n }\n}\n\nfunction runText(command: string, args: string[], env: NodeJS.ProcessEnv) {\n const run = spawnSync(command, args, { encoding: 'utf8', env, timeout: 8_000 })\n return {\n ok: run.status === 0 && !run.error,\n stdout: String(run.stdout || '').trim(),\n }\n}\n\nfunction firstLine(text: string): string {\n return text.split(/\\r?\\n/, 1)[0]?.trim() || ''\n}\n\nfunction versionAtLeast(actual: string, minimum: string): boolean {\n const a = actual.split('.').map((part) => Number.parseInt(part, 10) || 0)\n const b = minimum.split('.').map((part) => Number.parseInt(part, 10) || 0)\n for (let i = 0; i < Math.max(a.length, b.length); i += 1) {\n if ((a[i] || 0) > (b[i] || 0)) return true\n if ((a[i] || 0) < (b[i] || 0)) return false\n }\n return true\n}\n"]}
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/doctor.ts"],"names":[],"mappings":"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","sourcesContent":["import { accessSync, constants, existsSync, readFileSync } from 'node:fs'\nimport { delimiter, dirname, join, resolve } from 'node:path'\nimport { homedir } from 'node:os'\nimport { spawnSync } from 'node:child_process'\n\nimport {\n BUNDLED_SKILL_NAMES, GLOBAL_SKILL_NAME, INSTALLABLE_SKILL_NAMES, skillStatus, skillSuiteStatus,\n type GlobalSkillStatus,\n} from './skill-manager.js'\n\nexport type CheckLevel = 'pass' | 'warn' | 'fail'\n\nexport interface DoctorCheck {\n id: 'node' | 'cli' | 'dws' | 'dws-auth' | 'skill' | 'claude-code' | 'codex' | 'opencode'\n level: CheckLevel\n summary: string\n detail?: string\n fix?: string\n}\n\nexport interface DoctorReport {\n $schema: 'dingtalk-agent/doctor@1'\n ready: boolean\n checks: DoctorCheck[]\n nextSteps: string[]\n skill: GlobalSkillStatus\n skills: GlobalSkillStatus[]\n}\n\nexport interface DoctorOptions {\n home?: string\n env?: NodeJS.ProcessEnv\n}\n\nexport function doctor(packageRoot: string, options: DoctorOptions = {}): DoctorReport {\n const home = options.home || homedir()\n const env = options.env || process.env\n const checks: DoctorCheck[] = []\n const pkg = JSON.parse(readFileSync(join(packageRoot, 'package.json'), 'utf8'))\n const version = String(pkg.version || '')\n\n const nodeVersion = process.versions.node\n checks.push(versionAtLeast(nodeVersion, '18.3.0')\n ? { id: 'node', level: 'pass', summary: `Node.js ${nodeVersion}` }\n : {\n id: 'node', level: 'fail', summary: `Node.js ${nodeVersion} 过旧`,\n fix: '升级到 Node.js 18.3 或更高版本',\n })\n\n const cli = findExecutable('dingtalk-agent', env)\n const alias = findExecutable('dta', env)\n if (cli && alias) {\n const installed = runText(cli, ['--version'], env)\n const aliasRun = runText(alias, ['--version'], env)\n const installedVersion = installed.ok ? firstLine(installed.stdout) : ''\n const aliasVersion = aliasRun.ok ? firstLine(aliasRun.stdout) : ''\n checks.push(installedVersion === version && aliasVersion === version\n ? {\n id: 'cli', level: 'pass', summary: `CLI ${installedVersion} 已在 PATH 中(dta 可用)`,\n detail: `${cli} · ${alias}`,\n }\n : {\n id: 'cli', level: 'warn', summary: 'PATH 中的 CLI 版本与当前包不一致',\n detail: `${cli} (${installedVersion || '无法识别版本'}) · ${alias} (${aliasVersion || '无法识别版本'})`,\n fix: `运行 npx --yes --registry=https://registry.npmjs.org @xdxer/dingtalk-agent@${version} setup`,\n })\n } else if (cli || alias) {\n checks.push({\n id: 'cli', level: 'fail', summary: 'CLI 入口不完整:dingtalk-agent 与 dta 应同时存在',\n detail: `dingtalk-agent=${cli || 'missing'} · dta=${alias || 'missing'}`,\n fix: `运行 npx --yes --registry=https://registry.npmjs.org @xdxer/dingtalk-agent@${version} setup`,\n })\n } else {\n checks.push({\n id: 'cli', level: 'fail', summary: 'PATH 找不到 dingtalk-agent',\n detail: `当前 PATH=${env.PATH || ''}`,\n fix: `运行 npx --yes --registry=https://registry.npmjs.org @xdxer/dingtalk-agent@${version} setup`,\n })\n }\n\n const dws = findExecutable('dws', env)\n if (!dws) {\n checks.push({\n id: 'dws', level: 'fail', summary: 'PATH 找不到 dws',\n fix: '安装 DWS,并确认 `dws version --format json` 可以执行',\n })\n checks.push({\n id: 'dws-auth', level: 'fail', summary: '无法检查 DWS 认证',\n fix: 'DWS 可用后运行 `dws auth login`',\n })\n } else {\n const versionRun = runJson(dws, ['version', '--format', 'json'], env)\n const dwsVersion = versionRun.json?.version || firstLine(versionRun.stdout)\n const supported = versionRun.ok && versionAtLeast(String(dwsVersion || '').replace(/^v/, ''), '1.0.15')\n checks.push(supported\n ? { id: 'dws', level: 'pass', summary: `DWS ${dwsVersion || '可执行'}`, detail: dws }\n : {\n id: 'dws', level: 'fail',\n summary: versionRun.ok ? `DWS ${dwsVersion || ''} 低于最低版本 1.0.15` : 'DWS 存在但无法运行',\n detail: versionRun.ok ? dws : versionRun.error,\n fix: versionRun.ok ? '运行 `dws upgrade`' : '运行 `dws doctor` 检查安装',\n })\n\n const authRun = runJson(dws, ['auth', 'status', '--format', 'json'], env)\n const authenticated = authRun.ok && authRun.json?.authenticated === true &&\n authRun.json?.token_valid !== false\n checks.push(authenticated\n ? {\n id: 'dws-auth', level: 'pass', summary: 'DWS 已认证',\n detail: [authRun.json?.corp_name, authRun.json?.user_name].filter(Boolean).join(' · '),\n }\n : {\n id: 'dws-auth', level: 'fail', summary: 'DWS 尚未认证或凭据已失效',\n detail: authRun.error || 'authenticated=false', fix: '运行 `dws auth login`',\n })\n }\n\n const suite = skillSuiteStatus(packageRoot, { home })\n const skill = suite.skills.find((item) => item.name === GLOBAL_SKILL_NAME) || suite.skills[0]\n const allCurrent = suite.skills.every((item) => item.canonical.current)\n const anyMissing = suite.skills.some((item) => !item.canonical.exists)\n const installedSummary = suite.skills\n .map((item) => `${item.name} ${item.bundled.skillVersion}`).join(' + ')\n const staleSummary = suite.skills\n .filter((item) => !item.canonical.current)\n .map((item) => `${item.name} ${driftPhrase(item)}`).join('; ')\n // 平台 Skill 不属于默认套装:已安装才纳入报告,未安装既不提示也不影响 ready。\n const platformDrift = installedPlatformSkills(packageRoot, home)\n .filter((item) => !item.canonical.current)\n .map((item) => `${item.name} ${driftPhrase(item)}`)\n const detail = [\n suite.skills.map((item) => item.canonical.path).join(' · '),\n platformDrift.length ? `平台 Skill: ${platformDrift.join('; ')}` : '',\n ].filter(Boolean).join(' | ')\n checks.push(allCurrent && !platformDrift.length\n ? {\n id: 'skill', level: 'pass',\n summary: `内置 Skill 已安装: ${installedSummary}`,\n detail,\n }\n : {\n id: 'skill', level: anyMissing ? 'fail' : 'warn',\n summary: allCurrent\n ? `平台 Skill 需要更新: ${platformDrift.join('; ')}`\n : `内置 Skill 不完整: ${staleSummary}`,\n detail,\n fix: anyMissing\n ? '运行 `dingtalk-agent skill install`'\n : '运行 `dingtalk-agent skill status`,确认后执行 `dingtalk-agent skill upgrade`',\n })\n\n for (const client of skill.clients) {\n const states = suite.skills.map((item) => ({\n name: item.name,\n state: item.clients.find((entry) => entry.name === client.name)?.state || 'missing',\n }))\n const level: CheckLevel = states.some((item) => item.state === 'conflict')\n ? 'fail'\n : states.some((item) => item.state === 'missing') ? 'warn' : 'pass'\n checks.push({\n id: client.name,\n level,\n summary: `${client.label}: ${level === 'pass' ? '可发现内置 Skill' : level === 'fail' ? 'Skill 路径冲突' : '尚不可发现全部内置 Skill'}`,\n detail: `${client.discovery} · ${states.map((item) => `${item.name}=${item.state}`).join('; ')}`,\n fix: level === 'pass' ? undefined : '运行 `dingtalk-agent skill install`',\n })\n }\n\n const nextSteps = checks\n .filter((check) => check.level !== 'pass' && check.fix)\n .map((check) => check.fix as string)\n .filter((step, index, all) => all.indexOf(step) === index)\n return {\n $schema: 'dingtalk-agent/doctor@1',\n ready: !checks.some((check) => check.level === 'fail'),\n checks,\n nextSteps,\n skill,\n skills: suite.skills,\n }\n}\n\n/** 把漂移状态渲染成\"本机版本→包内版本(状态)\",让 doctor 输出能直接指出差距。 */\nfunction driftPhrase(item: GlobalSkillStatus): string {\n const installed = item.canonical.installedVersion || '—'\n return item.canonical.state === 'missing'\n ? '未安装(missing)'\n : `${installed}→${item.bundled.skillVersion}(${item.canonical.state})`\n}\n\n/** 已落地的平台 Skill;未安装的不返回,避免把 opt-in 能力报成缺失。 */\nfunction installedPlatformSkills(packageRoot: string, home?: string): GlobalSkillStatus[] {\n const core = new Set<string>(BUNDLED_SKILL_NAMES)\n const result: GlobalSkillStatus[] = []\n for (const name of INSTALLABLE_SKILL_NAMES) {\n if (core.has(name)) continue\n try {\n const status = skillStatus(packageRoot, { home, name })\n if (status.canonical.exists) result.push(status)\n } catch {\n // 平台 Skill 不可用不应让 doctor 失败;核心套装的问题由上面的 skill check 负责。\n }\n }\n return result\n}\n\nexport function findExecutable(command: string, env: NodeJS.ProcessEnv = process.env): string {\n const path = env.PATH || ''\n const extensions = process.platform === 'win32'\n ? (env.PATHEXT || '.EXE;.CMD;.BAT').split(';')\n : ['']\n for (const directory of path.split(delimiter).filter(Boolean)) {\n for (const extension of extensions) {\n const candidate = resolve(directory, command + extension.toLowerCase())\n try {\n accessSync(candidate, process.platform === 'win32' ? constants.F_OK : constants.X_OK)\n return candidate\n } catch { /* continue */ }\n }\n }\n return ''\n}\n\nfunction runJson(command: string, args: string[], env: NodeJS.ProcessEnv) {\n const run = spawnSync(command, args, { encoding: 'utf8', env, timeout: 8_000 })\n const stdout = String(run.stdout || '').trim()\n const stderr = String(run.stderr || '').trim()\n let json: any = null\n try { json = stdout ? JSON.parse(stdout) : null } catch { /* human output is allowed */ }\n return {\n ok: run.status === 0 && !run.error,\n json,\n stdout,\n error: run.error?.message || stderr || (run.signal ? `被 ${run.signal} 终止` : `退出码 ${run.status}`),\n }\n}\n\nfunction runText(command: string, args: string[], env: NodeJS.ProcessEnv) {\n const run = spawnSync(command, args, { encoding: 'utf8', env, timeout: 8_000 })\n return {\n ok: run.status === 0 && !run.error,\n stdout: String(run.stdout || '').trim(),\n }\n}\n\nfunction firstLine(text: string): string {\n return text.split(/\\r?\\n/, 1)[0]?.trim() || ''\n}\n\nfunction versionAtLeast(actual: string, minimum: string): boolean {\n const a = actual.split('.').map((part) => Number.parseInt(part, 10) || 0)\n const b = minimum.split('.').map((part) => Number.parseInt(part, 10) || 0)\n for (let i = 0; i < Math.max(a.length, b.length); i += 1) {\n if ((a[i] || 0) > (b[i] || 0)) return true\n if ((a[i] || 0) < (b[i] || 0)) return false\n }\n return true\n}\n"]}
|
package/dist/src/map.js
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
// Managed Agents Platform(MAP)注册表与工作区归属解析。
|
|
2
|
+
//
|
|
3
|
+
// 一个 Agent 工作区归属于至多一个托管平台;归属解析顺序固定:
|
|
4
|
+
// DTA_MAP 环境变量 > dingtalk-agent.json#map > .dingtalk-agent/map.json > 按 Provider 声明推断。
|
|
5
|
+
// 平台相关的方法学不写进 CLI——它们随对应平台的 Skill 包分发,只在用户选择该平台时安装。
|
|
6
|
+
// 平台命令(如 deploy/promote/observe)必须先通过归属门禁;coming-soon 平台一律 fail-closed。
|
|
7
|
+
import { existsSync, lstatSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
8
|
+
import { dirname, join, parse, resolve } from 'node:path';
|
|
9
|
+
import { findAgentProjectRoot } from './development-workspace.js';
|
|
10
|
+
import { installGlobalSkill } from './skill-manager.js';
|
|
11
|
+
export const MANAGED_AGENT_PLATFORMS = [
|
|
12
|
+
{
|
|
13
|
+
name: 'multica-dingtalk',
|
|
14
|
+
label: 'Multica (DingTalk)',
|
|
15
|
+
status: 'supported',
|
|
16
|
+
description: '钉钉 Multica 托管平台:受控部署、晋级与观测回流。',
|
|
17
|
+
skills: ['dingtalk-agent-deploy', 'dingtalk-agent-boot-multica'],
|
|
18
|
+
commands: ['deploy', 'promote', 'observe'],
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: 'deap',
|
|
22
|
+
label: 'DEAP',
|
|
23
|
+
status: 'coming-soon',
|
|
24
|
+
description: '敬请期待。',
|
|
25
|
+
skills: [],
|
|
26
|
+
commands: [],
|
|
27
|
+
},
|
|
28
|
+
];
|
|
29
|
+
export const MAP_FILE = '.dingtalk-agent/map.json';
|
|
30
|
+
const PROJECT_FILE = 'dingtalk-agent.json';
|
|
31
|
+
export function mapDefinition(name) {
|
|
32
|
+
return MANAGED_AGENT_PLATFORMS.find((item) => item.name === name) || null;
|
|
33
|
+
}
|
|
34
|
+
export function resolveMap(start = process.cwd(), env = process.env) {
|
|
35
|
+
const fromEnv = String(env.DTA_MAP || '').trim();
|
|
36
|
+
if (fromEnv)
|
|
37
|
+
return resolution(fromEnv, 'env', '');
|
|
38
|
+
const projectRoot = findAgentProjectRoot(start);
|
|
39
|
+
if (projectRoot) {
|
|
40
|
+
const manifestPath = join(projectRoot, PROJECT_FILE);
|
|
41
|
+
if (existsSync(manifestPath) && !lstatSync(manifestPath).isSymbolicLink()) {
|
|
42
|
+
const manifest = readJsonOrNull(manifestPath);
|
|
43
|
+
const declared = typeof manifest?.map === 'string' ? manifest.map.trim() : '';
|
|
44
|
+
if (declared)
|
|
45
|
+
return resolution(declared, 'project-manifest', manifestPath);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
const mapPath = findUp(start, MAP_FILE);
|
|
49
|
+
if (mapPath) {
|
|
50
|
+
const stored = readJsonOrNull(mapPath);
|
|
51
|
+
const declared = typeof stored?.map === 'string' ? stored.map.trim() : '';
|
|
52
|
+
if (declared)
|
|
53
|
+
return resolution(declared, 'map-file', mapPath);
|
|
54
|
+
}
|
|
55
|
+
if (projectRoot) {
|
|
56
|
+
const manifest = readJsonOrNull(join(projectRoot, PROJECT_FILE));
|
|
57
|
+
const providers = Object.values(manifest?.workspaces || {})
|
|
58
|
+
.map((workspace) => workspace?.provider?.kind);
|
|
59
|
+
if (providers.includes('multica')) {
|
|
60
|
+
return resolution('multica-dingtalk', 'inferred', join(projectRoot, PROJECT_FILE));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return resolution(null, 'none', '');
|
|
64
|
+
}
|
|
65
|
+
export function useMap(start, name, options) {
|
|
66
|
+
const definition = mapDefinition(name);
|
|
67
|
+
if (!definition) {
|
|
68
|
+
throw new Error(`未知 managed agents platform: ${name}\n` +
|
|
69
|
+
`可用: ${MANAGED_AGENT_PLATFORMS.map((item) => `${item.name}(${statusLabel(item.status)})`).join('、')}`);
|
|
70
|
+
}
|
|
71
|
+
if (definition.status !== 'supported') {
|
|
72
|
+
throw new Error(`${definition.label} 敬请期待——当前版本尚未开放该平台。`);
|
|
73
|
+
}
|
|
74
|
+
const projectRoot = findAgentProjectRoot(start);
|
|
75
|
+
let written;
|
|
76
|
+
if (projectRoot && existsSync(join(projectRoot, PROJECT_FILE))) {
|
|
77
|
+
const manifestPath = join(projectRoot, PROJECT_FILE);
|
|
78
|
+
if (lstatSync(manifestPath).isSymbolicLink()) {
|
|
79
|
+
throw new Error(`${PROJECT_FILE} 不能是符号链接`);
|
|
80
|
+
}
|
|
81
|
+
const manifest = readJsonOrNull(manifestPath);
|
|
82
|
+
if (!manifest || typeof manifest !== 'object') {
|
|
83
|
+
throw new Error(`${PROJECT_FILE} 不是合法 JSON,无法写入 map 归属`);
|
|
84
|
+
}
|
|
85
|
+
manifest.map = definition.name;
|
|
86
|
+
writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + '\n');
|
|
87
|
+
written = manifestPath;
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
const target = join(resolve(start), MAP_FILE);
|
|
91
|
+
mkdirSync(dirname(target), { recursive: true });
|
|
92
|
+
writeFileSync(target, JSON.stringify({ $schema: 'dingtalk-agent/map@1', map: definition.name }, null, 2) + '\n');
|
|
93
|
+
written = target;
|
|
94
|
+
}
|
|
95
|
+
const skillInstalls = [];
|
|
96
|
+
if (options.installSkills !== false) {
|
|
97
|
+
for (const skill of definition.skills) {
|
|
98
|
+
skillInstalls.push(installGlobalSkill(options.packageRoot, {
|
|
99
|
+
name: skill, home: options.home, env: options.env,
|
|
100
|
+
}));
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return { ...resolveMap(start, options.env || process.env), written, skillInstalls };
|
|
104
|
+
}
|
|
105
|
+
/** deploy/promote/observe 等平台命令的归属门禁:未归属、未知或 coming-soon 一律 fail-closed。 */
|
|
106
|
+
export function requireSupportedMap(command, start = process.cwd(), env = process.env) {
|
|
107
|
+
const resolved = resolveMap(start, env);
|
|
108
|
+
if (!resolved.map) {
|
|
109
|
+
throw new Error(`当前工作区未声明 managed agents platform,无法执行 \`${command}\`。\n` +
|
|
110
|
+
'先运行 `dta map use multica-dingtalk`,或设置 DTA_MAP 环境变量。');
|
|
111
|
+
}
|
|
112
|
+
if (!resolved.definition) {
|
|
113
|
+
throw new Error(`工作区声明了未知 platform: ${resolved.map}(来源 ${resolved.source})。\n` +
|
|
114
|
+
`可用: ${MANAGED_AGENT_PLATFORMS.map((item) => item.name).join('、')}`);
|
|
115
|
+
}
|
|
116
|
+
if (resolved.definition.status !== 'supported') {
|
|
117
|
+
throw new Error(`${resolved.definition.label} 敬请期待——\`${command}\` 尚未在该平台开放。`);
|
|
118
|
+
}
|
|
119
|
+
if (!resolved.definition.commands.includes(command)) {
|
|
120
|
+
throw new Error(`${resolved.definition.label} 不承接命令 \`${command}\`。`);
|
|
121
|
+
}
|
|
122
|
+
return resolved;
|
|
123
|
+
}
|
|
124
|
+
export function statusLabel(status) {
|
|
125
|
+
return status === 'supported' ? '已支持' : '敬请期待';
|
|
126
|
+
}
|
|
127
|
+
function resolution(name, source, file) {
|
|
128
|
+
return {
|
|
129
|
+
$schema: 'dingtalk-agent/map-resolution@1',
|
|
130
|
+
map: name,
|
|
131
|
+
source,
|
|
132
|
+
file,
|
|
133
|
+
definition: name ? mapDefinition(name) : null,
|
|
134
|
+
platforms: MANAGED_AGENT_PLATFORMS,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
function readJsonOrNull(path) {
|
|
138
|
+
try {
|
|
139
|
+
return JSON.parse(readFileSync(path, 'utf8'));
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
function findUp(start, relativePath) {
|
|
146
|
+
let dir = resolve(start);
|
|
147
|
+
while (true) {
|
|
148
|
+
const candidate = join(dir, relativePath);
|
|
149
|
+
if (existsSync(candidate) && !lstatSync(candidate).isSymbolicLink())
|
|
150
|
+
return candidate;
|
|
151
|
+
const parent = dirname(dir);
|
|
152
|
+
if (parent === dir || dir === parse(dir).root)
|
|
153
|
+
return null;
|
|
154
|
+
dir = parent;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=map.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"map.js","sourceRoot":"","sources":["../../src/map.ts"],"names":[],"mappings":"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","sourcesContent":["// Managed Agents Platform(MAP)注册表与工作区归属解析。\n//\n// 一个 Agent 工作区归属于至多一个托管平台;归属解析顺序固定:\n// DTA_MAP 环境变量 > dingtalk-agent.json#map > .dingtalk-agent/map.json > 按 Provider 声明推断。\n// 平台相关的方法学不写进 CLI——它们随对应平台的 Skill 包分发,只在用户选择该平台时安装。\n// 平台命令(如 deploy/promote/observe)必须先通过归属门禁;coming-soon 平台一律 fail-closed。\n\nimport { existsSync, lstatSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { dirname, join, parse, resolve } from 'node:path'\n\nimport { findAgentProjectRoot } from './development-workspace.js'\nimport { installGlobalSkill, type GlobalSkillStatus } from './skill-manager.js'\n\nexport type MapStatus = 'supported' | 'coming-soon'\n\nexport interface MapDefinition {\n name: string\n label: string\n status: MapStatus\n description: string\n skills: string[]\n commands: string[]\n}\n\nexport const MANAGED_AGENT_PLATFORMS: MapDefinition[] = [\n {\n name: 'multica-dingtalk',\n label: 'Multica (DingTalk)',\n status: 'supported',\n description: '钉钉 Multica 托管平台:受控部署、晋级与观测回流。',\n skills: ['dingtalk-agent-deploy', 'dingtalk-agent-boot-multica'],\n commands: ['deploy', 'promote', 'observe'],\n },\n {\n name: 'deap',\n label: 'DEAP',\n status: 'coming-soon',\n description: '敬请期待。',\n skills: [],\n commands: [],\n },\n]\n\nexport const MAP_FILE = '.dingtalk-agent/map.json'\nconst PROJECT_FILE = 'dingtalk-agent.json'\n\nexport type MapSource = 'env' | 'project-manifest' | 'map-file' | 'inferred' | 'none'\n\nexport interface MapResolution {\n $schema: 'dingtalk-agent/map-resolution@1'\n map: string | null\n source: MapSource\n file: string\n definition: MapDefinition | null\n platforms: MapDefinition[]\n}\n\nexport interface MapUseResult extends MapResolution {\n written: string\n skillInstalls: GlobalSkillStatus[]\n}\n\nexport function mapDefinition(name: string): MapDefinition | null {\n return MANAGED_AGENT_PLATFORMS.find((item) => item.name === name) || null\n}\n\nexport function resolveMap(start = process.cwd(), env: NodeJS.ProcessEnv = process.env): MapResolution {\n const fromEnv = String(env.DTA_MAP || '').trim()\n if (fromEnv) return resolution(fromEnv, 'env', '')\n\n const projectRoot = findAgentProjectRoot(start)\n if (projectRoot) {\n const manifestPath = join(projectRoot, PROJECT_FILE)\n if (existsSync(manifestPath) && !lstatSync(manifestPath).isSymbolicLink()) {\n const manifest = readJsonOrNull(manifestPath)\n const declared = typeof manifest?.map === 'string' ? manifest.map.trim() : ''\n if (declared) return resolution(declared, 'project-manifest', manifestPath)\n }\n }\n\n const mapPath = findUp(start, MAP_FILE)\n if (mapPath) {\n const stored = readJsonOrNull(mapPath)\n const declared = typeof stored?.map === 'string' ? stored.map.trim() : ''\n if (declared) return resolution(declared, 'map-file', mapPath)\n }\n\n if (projectRoot) {\n const manifest = readJsonOrNull(join(projectRoot, PROJECT_FILE))\n const providers = Object.values(manifest?.workspaces || {})\n .map((workspace: any) => workspace?.provider?.kind)\n if (providers.includes('multica')) {\n return resolution('multica-dingtalk', 'inferred', join(projectRoot, PROJECT_FILE))\n }\n }\n\n return resolution(null, 'none', '')\n}\n\nexport interface MapUseOptions {\n packageRoot: string\n home?: string\n env?: NodeJS.ProcessEnv\n installSkills?: boolean\n}\n\nexport function useMap(start: string, name: string, options: MapUseOptions): MapUseResult {\n const definition = mapDefinition(name)\n if (!definition) {\n throw new Error(\n `未知 managed agents platform: ${name}\\n` +\n `可用: ${MANAGED_AGENT_PLATFORMS.map((item) => `${item.name}(${statusLabel(item.status)})`).join('、')}`,\n )\n }\n if (definition.status !== 'supported') {\n throw new Error(`${definition.label} 敬请期待——当前版本尚未开放该平台。`)\n }\n\n const projectRoot = findAgentProjectRoot(start)\n let written: string\n if (projectRoot && existsSync(join(projectRoot, PROJECT_FILE))) {\n const manifestPath = join(projectRoot, PROJECT_FILE)\n if (lstatSync(manifestPath).isSymbolicLink()) {\n throw new Error(`${PROJECT_FILE} 不能是符号链接`)\n }\n const manifest = readJsonOrNull(manifestPath)\n if (!manifest || typeof manifest !== 'object') {\n throw new Error(`${PROJECT_FILE} 不是合法 JSON,无法写入 map 归属`)\n }\n manifest.map = definition.name\n writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + '\\n')\n written = manifestPath\n } else {\n const target = join(resolve(start), MAP_FILE)\n mkdirSync(dirname(target), { recursive: true })\n writeFileSync(target, JSON.stringify(\n { $schema: 'dingtalk-agent/map@1', map: definition.name }, null, 2,\n ) + '\\n')\n written = target\n }\n\n const skillInstalls: GlobalSkillStatus[] = []\n if (options.installSkills !== false) {\n for (const skill of definition.skills) {\n skillInstalls.push(installGlobalSkill(options.packageRoot, {\n name: skill, home: options.home, env: options.env,\n }))\n }\n }\n\n return { ...resolveMap(start, options.env || process.env), written, skillInstalls }\n}\n\n/** deploy/promote/observe 等平台命令的归属门禁:未归属、未知或 coming-soon 一律 fail-closed。 */\nexport function requireSupportedMap(\n command: string, start = process.cwd(), env: NodeJS.ProcessEnv = process.env,\n): MapResolution {\n const resolved = resolveMap(start, env)\n if (!resolved.map) {\n throw new Error(\n `当前工作区未声明 managed agents platform,无法执行 \\`${command}\\`。\\n` +\n '先运行 `dta map use multica-dingtalk`,或设置 DTA_MAP 环境变量。',\n )\n }\n if (!resolved.definition) {\n throw new Error(\n `工作区声明了未知 platform: ${resolved.map}(来源 ${resolved.source})。\\n` +\n `可用: ${MANAGED_AGENT_PLATFORMS.map((item) => item.name).join('、')}`,\n )\n }\n if (resolved.definition.status !== 'supported') {\n throw new Error(`${resolved.definition.label} 敬请期待——\\`${command}\\` 尚未在该平台开放。`)\n }\n if (!resolved.definition.commands.includes(command)) {\n throw new Error(`${resolved.definition.label} 不承接命令 \\`${command}\\`。`)\n }\n return resolved\n}\n\nexport function statusLabel(status: MapStatus): string {\n return status === 'supported' ? '已支持' : '敬请期待'\n}\n\nfunction resolution(name: string | null, source: MapSource, file: string): MapResolution {\n return {\n $schema: 'dingtalk-agent/map-resolution@1',\n map: name,\n source,\n file,\n definition: name ? mapDefinition(name) : null,\n platforms: MANAGED_AGENT_PLATFORMS,\n }\n}\n\nfunction readJsonOrNull(path: string): any {\n try { return JSON.parse(readFileSync(path, 'utf8')) } catch { return null }\n}\n\nfunction findUp(start: string, relativePath: string): string | null {\n let dir = resolve(start)\n while (true) {\n const candidate = join(dir, relativePath)\n if (existsSync(candidate) && !lstatSync(candidate).isSymbolicLink()) return candidate\n const parent = dirname(dir)\n if (parent === dir || dir === parse(dir).root) return null\n dir = parent\n }\n}\n"]}
|
|
@@ -81,7 +81,7 @@ export function planMulticaDeployment(start, name, options = {}) {
|
|
|
81
81
|
workspaceId: readPlan.expected.workspaceId,
|
|
82
82
|
runtimeId: readPlan.expected.runtimeId,
|
|
83
83
|
agentId: readPlan.expected.agentId,
|
|
84
|
-
agentName: info.project.
|
|
84
|
+
agentName: info.project.displayName,
|
|
85
85
|
skills: expectedSkills,
|
|
86
86
|
definitionHash: source.definitionHash,
|
|
87
87
|
instructionsHash: source.instructionsHash,
|
|
@@ -599,24 +599,20 @@ function readSmoke(root, plan, marker, issueId, agentId, requiredSkills, command
|
|
|
599
599
|
'issue', 'run-messages', taskId, '--issue', issueId, '--output', 'json',
|
|
600
600
|
]), 'smoke.issue.messages', 'read', root, env, timeoutMs, calls).stdout, 'smoke messages');
|
|
601
601
|
const toolUses = messages.filter((item) => optionalString(item.type) === 'tool_use');
|
|
602
|
-
const
|
|
603
|
-
const
|
|
602
|
+
const skillToolUses = toolUses.filter((item) => optionalString(item.tool) === 'skill');
|
|
603
|
+
const skillNames = skillToolUses.map((item) => smokeToolInput(item).name)
|
|
604
|
+
.filter((item) => typeof item === 'string' && Boolean(item)).sort();
|
|
605
|
+
const loadedSkills = requiredSkills.filter((name) => skillNames.includes(name)).sort();
|
|
604
606
|
const texts = messages.filter((item) => optionalString(item.type) === 'text')
|
|
605
607
|
.map((item) => optionalString(item.content)).filter(Boolean);
|
|
606
608
|
const finalText = texts.at(-1) || '';
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
}
|
|
615
|
-
catch {
|
|
616
|
-
responsePassed = false;
|
|
617
|
-
}
|
|
618
|
-
const toolTracePassed = nonSkillTools.length === 0 &&
|
|
619
|
-
stableStringify(loadedSkills) === stableStringify(requiredSkills);
|
|
609
|
+
const matchesResponse = (value) => smokeResponseMatches(value, marker, requiredSkills);
|
|
610
|
+
const replyWrites = toolUses.filter((item) => optionalString(item.tool) === 'write')
|
|
611
|
+
.map((item) => smokeToolInput(item)).filter((input) => optionalString(input.filePath).endsWith('/reply.md'))
|
|
612
|
+
.map((input) => optionalString(input.content)).filter(Boolean);
|
|
613
|
+
const responseEvidence = [...texts, ...replyWrites].find(matchesResponse) || '';
|
|
614
|
+
const responsePassed = Boolean(responseEvidence);
|
|
615
|
+
const toolTracePassed = toolUses.every((item) => allowedSmokeToolUse(item, issueId, marker, requiredSkills)) && stableStringify(skillNames) === stableStringify(requiredSkills);
|
|
620
616
|
const failures = [];
|
|
621
617
|
if (taskStatus !== 'completed')
|
|
622
618
|
failures.push(`smoke.task.${taskStatus || 'unknown'}`);
|
|
@@ -627,9 +623,70 @@ function readSmoke(root, plan, marker, issueId, agentId, requiredSkills, command
|
|
|
627
623
|
return {
|
|
628
624
|
status: failures.length ? 'failed' : 'passed',
|
|
629
625
|
marker, markerHash: sha256(marker), issueId, taskId, taskStatus, requiredSkills, loadedSkills,
|
|
630
|
-
toolTracePassed, responsePassed, responseHash: sha256(finalText), failures,
|
|
626
|
+
toolTracePassed, responsePassed, responseHash: sha256(responseEvidence || finalText), failures,
|
|
631
627
|
};
|
|
632
628
|
}
|
|
629
|
+
function smokeToolInput(item) {
|
|
630
|
+
return item.input && typeof item.input === 'object' && !Array.isArray(item.input)
|
|
631
|
+
? item.input : {};
|
|
632
|
+
}
|
|
633
|
+
function smokeResponseMatches(value, marker, requiredSkills) {
|
|
634
|
+
try {
|
|
635
|
+
const parsed = JSON.parse(value);
|
|
636
|
+
return parsed?.schema === 'dta-multica-load-smoke@1' && parsed?.marker === marker &&
|
|
637
|
+
stableStringify(Array.isArray(parsed?.loaded) ? [...parsed.loaded].sort() : []) ===
|
|
638
|
+
stableStringify(requiredSkills);
|
|
639
|
+
}
|
|
640
|
+
catch {
|
|
641
|
+
return false;
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
function allowedSmokeToolUse(item, issueId, marker, requiredSkills) {
|
|
645
|
+
const tool = optionalString(item.tool);
|
|
646
|
+
if (tool === 'skill')
|
|
647
|
+
return true;
|
|
648
|
+
const input = smokeToolInput(item);
|
|
649
|
+
if (tool === 'write') {
|
|
650
|
+
return safeSmokeReplyPath(optionalString(input.filePath)) &&
|
|
651
|
+
smokeResponseMatches(optionalString(input.content), marker, requiredSkills);
|
|
652
|
+
}
|
|
653
|
+
if (tool !== 'bash')
|
|
654
|
+
return false;
|
|
655
|
+
const command = optionalString(input.command);
|
|
656
|
+
if (new Set([
|
|
657
|
+
`multica issue get ${issueId} --output json`,
|
|
658
|
+
`multica issue metadata list ${issueId} --output json`,
|
|
659
|
+
`multica issue comment list ${issueId} --recent 10 --output json`,
|
|
660
|
+
`multica issue status ${issueId} in_progress`,
|
|
661
|
+
`multica issue status ${issueId} in_review`,
|
|
662
|
+
]).has(command))
|
|
663
|
+
return true;
|
|
664
|
+
const commentPrefix = `multica issue comment add ${issueId} --content-file `;
|
|
665
|
+
if (command.startsWith(commentPrefix)) {
|
|
666
|
+
return safeSmokeReplyPath(command.slice(commentPrefix.length));
|
|
667
|
+
}
|
|
668
|
+
const cleanupFirstPrefix = 'rm ';
|
|
669
|
+
const cleanupFirstSuffix = ` && multica issue status ${issueId} in_review`;
|
|
670
|
+
if (command.startsWith(cleanupFirstPrefix) && command.endsWith(cleanupFirstSuffix)) {
|
|
671
|
+
return safeSmokeReplyPath(command.slice(cleanupFirstPrefix.length, command.length - cleanupFirstSuffix.length));
|
|
672
|
+
}
|
|
673
|
+
const statusFirstPrefix = `multica issue status ${issueId} in_review && rm `;
|
|
674
|
+
if (command.startsWith(statusFirstPrefix)) {
|
|
675
|
+
return safeSmokeReplyPath(command.slice(statusFirstPrefix.length));
|
|
676
|
+
}
|
|
677
|
+
if (command.startsWith(cleanupFirstPrefix)) {
|
|
678
|
+
return safeSmokeReplyPath(command.slice(cleanupFirstPrefix.length));
|
|
679
|
+
}
|
|
680
|
+
return false;
|
|
681
|
+
}
|
|
682
|
+
function safeSmokeReplyPath(value) {
|
|
683
|
+
if (value === './reply.md')
|
|
684
|
+
return true;
|
|
685
|
+
if (!value.startsWith('/') || !value.endsWith('/reply.md'))
|
|
686
|
+
return false;
|
|
687
|
+
return value.split('/').every((part) => !part ||
|
|
688
|
+
(part !== '.' && part !== '..' && /^[A-Za-z0-9._-]+$/.test(part)));
|
|
689
|
+
}
|
|
633
690
|
function rollbackConfirmed(root, plan, command, env, timeoutMs, calls, rollback, temp) {
|
|
634
691
|
const report = emptyRollback(true);
|
|
635
692
|
const attempt = (id, argv) => {
|
|
@@ -834,7 +891,7 @@ export function statusMulticaDeployment(start, name, options = {}) {
|
|
|
834
891
|
const matched = Boolean(snapshot && remoteMatchesDesired(snapshot, source, operation.runtimeId));
|
|
835
892
|
const safelyBound = Boolean(snapshot?.agent && inspection.passed &&
|
|
836
893
|
snapshot.agent.id === operation.agentId &&
|
|
837
|
-
snapshot.agent.name === info.project.
|
|
894
|
+
snapshot.agent.name === info.project.displayName &&
|
|
838
895
|
snapshot.agent.runtimeId === operation.runtimeId &&
|
|
839
896
|
snapshot.agent.instructions === source.instructions && !snapshot.agent.archived);
|
|
840
897
|
receipt = { ...receipt,
|
|
@@ -935,7 +992,7 @@ function reconcileRemoteTarget(root, name, operation, source, command, env, time
|
|
|
935
992
|
if (candidates.length > 10) {
|
|
936
993
|
return { inspection: discovery, snapshot: null, failures: ['reconcile.agent-candidate-budget'] };
|
|
937
994
|
}
|
|
938
|
-
const projectName = inspectAgentProject(root).project.
|
|
995
|
+
const projectName = inspectAgentProject(root).project.displayName;
|
|
939
996
|
const matches = [];
|
|
940
997
|
for (const [index, candidate] of candidates.entries()) {
|
|
941
998
|
const inspection = inspectMulticaWorkspace(root, name, {
|