mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
feat(app-boot): register cordis:group beside cordis:include
A composition that shares one `isolate` realm across rows needs a `cordis:group` row, and a preset living outside this workspace — the authored ones under the Harness home — cannot resolve `@cordisjs/plugin-group` by name: Node's upward `node_modules` walk never reaches the harness from there. Registering it as a loader builtin beside `cordis:include` loads both through the ambient module pipeline instead. Record it in the preset Agent Note, which leans on the realm vocabulary without saying where the group row comes from, and drop the preset README's limitation claiming this builtin is unavailable — it described the state this change ends. The test's assertion had a vacuous escape: `provide` mints the root symbol unconditionally, so the `rootKey === undefined` disjunct could never hold and the comment claiming the root realm never learned the name was wrong. Pin both halves — the symbol exists, nothing is stored under it — and clean up the global the fixture writes.
This commit is contained in:
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-03-per-session-agent-presets.md
|
||||
2026-08-03-per-session-agent-presets.md: ee6303e5f52234d7eaf6768043c92a15e4e5399f
|
||||
2026-08-03-per-session-agent-presets.zh.md: 5a2e1c3d8d0564f06c75785e1080b53740751355
|
||||
2026-08-03-per-session-agent-presets.md: dbe4188fe16a01b51f01cddf8a2387471e5e00a9
|
||||
2026-08-03-per-session-agent-presets.zh.md: aa7792a7db3a686b74f19ace130ad8f7b6d2feb6
|
||||
|
||||
@@ -29,6 +29,8 @@ Mounting is per-session by default. Measured cost for a twelve-row composition i
|
||||
|
||||
**A directly-plugged subtree is invisible to the boot audit.** It never links itself to an `Entry`, so it is absent from `ctx.loader.entries()` and `assertEntriesActivated` cannot see it. The mount audits its own rows instead, reading the tree through an `Include` subclass that publishes it.
|
||||
|
||||
**A preset can only name a group because the app registers one.** Sharing a realm across rows is a `cordis:group` row, and a preset living outside this workspace — the authored ones under the Harness home, which is the point — cannot resolve `@cordisjs/plugin-group` by name: Node's upward `node_modules` walk never reaches the harness from there. `boot()` therefore registers `cordis:group` beside `cordis:include` as a loader builtin, so both load through the ambient module pipeline rather than through the included tree's own specifier resolution. Without it the `isolate` vocabulary above is expressible one row at a time only, and a provider could never be grouped with its consumers.
|
||||
|
||||
**A preset may not publish into the root service realm.** Such a service is process-global rather than per-session, so the second session mounting the same preset collides with the first — and the collision surfaces as an unhandled rejection that `setup` never observes, leaving a half-composed agent that looks healthy. The mount rejects it instead, and the package invariant re-checks on every service notification because a row publishing from a timer or an asynchronous continuation would escape a one-shot audit.
|
||||
|
||||
**Failure rolls the agent back.** `setup` runs before publication, so a rejected mount fails `ctx.agents.create()` and leaves nothing behind. This is why `setup` is the one supported call site.
|
||||
|
||||
@@ -29,6 +29,8 @@ Status: implemented
|
||||
|
||||
**直接挂载的子树对启动审计不可见。** 它不会把自己关联到 `Entry`,因此不在 `ctx.loader.entries()` 中,`assertEntriesActivated` 也看不到它。改由挂载过程自行校验各行,通过一个会公开自身 tree 的 `Include` 子类读取。
|
||||
|
||||
**preset 能写出 group,是因为 app 注册了它。** 跨行共享 realm 就是一个 `cordis:group` 行,而住在本工作区之外的 preset——也就是 Harness home 下由人或 agent 创作的那些,正是这套设计的目的——无法按名字解析 `@cordisjs/plugin-group`:Node 向上查找 `node_modules` 的路径从那里永远走不到 harness。因此 `boot()` 把 `cordis:group` 与 `cordis:include` 并排注册为 loader builtin,两者都经由环境模块管线加载,而不依赖被包含树自身的说明符解析。没有它,上文那套 `isolate` 词汇就只能一行一行地表达,提供方也永远无法与它的消费方归入同一组。
|
||||
|
||||
**preset 不得把服务发布进根 realm。** 这类服务是进程级全局而非按会话的,因此第二个挂载同一 preset 的会话会与第一个相撞——而这次相撞表现为 `setup` 永远观察不到的未处理 rejection,留下一个看起来健康、实则组装到一半的 agent。挂载改为直接拒绝它;本包的运行时不变量还会在每次服务通知时复查,因为从定时器或异步续体中发布的行会绕过一次性审计。
|
||||
|
||||
**失败会让 agent 回滚。** `setup` 在发布之前运行,因此挂载被拒绝会让 `ctx.agents.create()` 失败且不留残留。这正是 `setup` 是唯一受支持调用点的原因。
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/preset/agent-presets/README.md
|
||||
README.md: 5d66c23f24717d1c30a9e729c7b0528715692d41
|
||||
README.zh.md: 9cdcd8b11a8a37d6d789c393e9a1500e4fbfd503
|
||||
README.md: e53a52f145b3f66ab115b93c614561fed8194719
|
||||
README.zh.md: 39b470002816f309c8ec9af1d72e04495b020ad7
|
||||
|
||||
@@ -58,5 +58,4 @@ Prefix-stable for the life of an agent: a composition is installed once, before
|
||||
|
||||
- **A preset cannot be changed on a live agent** — the mount happens once during creation, so switching a running session's composition would mean unwinding its subtree mid-turn, dropping tools the model may already have called. Changing the default affects only sessions created afterwards.
|
||||
- **Display names are the directory id** — a preset carries no manifest, so pickers and settings surfaces show the id until a consumer needs richer metadata.
|
||||
- **`isolate` realms cannot be expressed across rows without `cordis:group`** — an entry-local realm works on a single row, but grouping a provider with its consumers under one shared realm needs the group builtin, which `dsh-app-boot` does not register.
|
||||
- **Root scans are not watched** — every read hits the filesystem instead, which keeps the roster fresh but puts one `readdir` per root on each `list()`.
|
||||
|
||||
@@ -58,5 +58,4 @@ Indirectly, through the plugins a mounted composition registers, which own every
|
||||
|
||||
- **无法在存活的 agent 上更换 preset** —— 挂载只在创建时发生一次,因此切换运行中会话的组装意味着要在轮次进行途中卸载其子树,抽走模型可能已经调用的工具。更改默认值只影响此后创建的会话。
|
||||
- **展示名称就是目录 id** —— preset 不携带 manifest,因此选择器与设置界面在有消费方需要更丰富的元数据之前,只显示 id。
|
||||
- **跨多行的 `isolate` realm 需要 `cordis:group` 才能表达** —— 单行可用 entry 本地 realm,但要把一个提供方与它的消费方归入同一个共享 realm,需要 group 内建插件,而 `dsh-app-boot` 并未注册它。
|
||||
- **根目录扫描不做监听** —— 每次读取都实际访问文件系统,这让名单保持新鲜,但每次 `list()` 会对每个根目录产生一次 `readdir`。
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/ui/app-boot/README.md
|
||||
README.md: cdd78047b6ad71148c6ebeba598b63b4ae4cfa7b
|
||||
README.zh.md: ee2b07884e68510e2b59b9f2c27053c263d15f1a
|
||||
README.md: 56df424b44564d6e8f6ccd0a61c258dacf9748d3
|
||||
README.zh.md: ddd8103e849bc6798b056cae92c88e5f84551108
|
||||
|
||||
@@ -14,7 +14,7 @@ Shared boot glue for the app bins ([`dsh`](../../../apps/cli/README.md), [`dsh-c
|
||||
| `assertEntriesActivated(ctx, binName)` | Include the `assertEntriesLoaded` check, then await every enabled entry after the Loader settles; throw with each failed plugin's original stack or each pending plugin's unresolved services |
|
||||
| `loadOptionalPatches(binName, file)` | Parse an optional patch-list file (a profile's `cordis.patch.yml`) — a top-level YAML array of include `PatchOptions` (id-targeted config overrides, `insert` lists, `!!js` allowed); absent file → `undefined`, an unreadable/unparsable/non-array file throws |
|
||||
| `loadOverlayPatches(binName, file)` | Parse a required patch-list file with the same shape; a missing file also throws, because the caller named it |
|
||||
| `mountRootInclude(ctx, absoluteConfigPath, patches?)` | Mount the statically imported Include builtin and retain the exact root entry used by user patch-layer HMR |
|
||||
| `mountRootInclude(ctx, absoluteConfigPath, patches?)` | Register the statically imported `cordis:include` and `cordis:group` builtins, mount the include, and retain the exact root entry used by user patch-layer HMR |
|
||||
| `watchUserPatches(ctx, options)` | Register the named patch file with the existing Cordis HMR service; each add/change/removal transactionally recomposes the full patch list through the caller's `compose` closure (app-owned layers around the current user layer) and returns an async disposer |
|
||||
| `resolveProfileDir` / `initProfile` / `loadProfile` / `readProfileManifest` / `writeProfileManifest` / `resolveBundleDir` / `composeEntries` / `healProfilesModuleFallback` / `PROFILE_TEMPLATES` / `DEFAULT_PROFILE_BUNDLES` / `PROFILES_DIR` / `PROFILE_PATCH_FILENAME` | Profile machinery (see [Profiles](#profiles)) |
|
||||
| `boot(binName, absoluteConfigPath, patches?, prepare?)` | Create the root context, expose `dshHomePath(...segments)` to Loader `!!js` config expressions, install Loader, run optional host preparation before config-tree entries mount (`prepare` may use Loader and provide launcher-owned context slots), then mount and await the include tree, assert entries loaded and activated, and return the root context — or dispose the partial context and reject a labelled error |
|
||||
@@ -26,6 +26,8 @@ Loader settlement rejects import and lifecycle failures with the failing entry a
|
||||
|
||||
The Loader mounts entries concurrently, so a surface can already own the terminal when something else fails: exiting without the tree's own teardown would leave raw mode, bracketed paste, and the keyboard protocol set on the user's shell, and an in-flight terminal query's reply would land as literal text at the next prompt. A config-tree failure settles through `boot()`, whose disposal of the partial context runs the surface's own shutdown before the labelled rejection. For the rejections `boot()` cannot see — a plugin's detached async work rejecting during or after mounting — a terminal-owning bin passes `release` to dispose the tree before the exit commits; `dsh` captures the root context in `boot()`'s `prepare` hook rather than from its return value so the hook covers the whole mounting window. While a release is in flight the handler stays installed and latched: the first rejection is the reported one, and later rejections (teardown's own included) are swallowed rather than becoming uncaught and killing the process mid-teardown.
|
||||
|
||||
`cordis:group` is registered beside `cordis:include` so a composition can give one `isolate` realm to a provider and its consumers together. Both load through the ambient module pipeline rather than the included tree's own specifier resolution, which is what lets a composition outside this workspace — an agent preset under the Harness home — use a group row at all.
|
||||
|
||||
Bare plugin specifiers in a config (`@deepseek-ai/dsh-*`, npm packages) resolve through the Cordis Loader's internal module loader. Repository bins install Loader's optional `node-addon-require-builtin` peer; external callers must supply it or install plugins where plain Node import resolution can find them. Relative specifiers resolve against the config directory without the native helper. The built `dsh-app-boot` artifact embeds the statically mounted Include implementation while leaving Loader external, so the include tree and host bind to one Loader peer. The `dsh` source launcher additionally maps manifest-declared workspace packages to their TypeScript source; its configuration gate requires every shipped raw/Web bare plugin to appear in the resolver manifest's `dependencies`.
|
||||
|
||||
This package carries no loader hooks and no dev-mode surface. The [`dsh` app](../../../apps/cli/README.md) owns its Node source-launch hook and consumes these helpers for the boot sequence; built consumers continue to use plain Node package resolution.
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
| `assertEntriesActivated(ctx, binName)` | 先执行 `assertEntriesLoaded` 检查,再在 Loader 结算后等待每个已启用配置项;抛出的错误包含每个失败插件的原始错误堆栈,或每个等待中插件尚未解析的服务 |
|
||||
| `loadOptionalPatches(binName, file)` | 解析一份可选的 patch 列表文件(即 profile 的 `cordis.patch.yml`):其顶层是一个 YAML 数组,内容为 include 的 `PatchOptions`(按 id 定位的配置覆盖、`insert` 列表,允许 `!!js`);文件不存在时返回 `undefined`,文件不可读、不可解析或内容不是数组时抛出异常 |
|
||||
| `loadOverlayPatches(binName, file)` | 解析一份形状相同的必需 patch 列表文件;文件缺失同样抛出异常,因为该文件是调用方指名的 |
|
||||
| `mountRootInclude(ctx, absoluteConfigPath, patches?)` | 挂载静态导入的 Include builtin,并保留用户 patch 层 HMR(热模块替换)使用的确切根配置项 |
|
||||
| `mountRootInclude(ctx, absoluteConfigPath, patches?)` | 注册静态导入的 `cordis:include` 与 `cordis:group` builtin,挂载 include,并保留用户 patch 层 HMR(热模块替换)使用的确切根配置项 |
|
||||
| `watchUserPatches(ctx, options)` | 向现有 Cordis HMR 服务注册指名的 patch 文件;每次新增、变更或移除都会通过调用方的 `compose` 闭包(应用自有层围绕当前用户层)以事务方式重新组合完整 patch 列表,并返回异步 disposer |
|
||||
| `resolveProfileDir` / `initProfile` / `loadProfile` / `readProfileManifest` / `writeProfileManifest` / `resolveBundleDir` / `composeEntries` / `healProfilesModuleFallback` / `PROFILE_TEMPLATES` / `DEFAULT_PROFILE_BUNDLES` / `PROFILES_DIR` / `PROFILE_PATCH_FILENAME` | Profile 机制(见 [Profile](#profiles)) |
|
||||
| `boot(binName, absoluteConfigPath, patches?, prepare?)` | 创建根上下文,向 Loader `!!js` 配置表达式暴露 `dshHomePath(...segments)` 并安装 Loader,在配置树条目挂载前执行可选的宿主准备操作(`prepare` 可以使用 Loader,也可以提供由启动器拥有的上下文插槽),再挂载并等待 include 树结算,断言所有条目均已加载并激活,最后返回根上下文——失败时 dispose(资源释放)部分构造的上下文,并以带标签的错误 reject |
|
||||
@@ -26,6 +26,8 @@ Loader 结算会在导入或生命周期失败时 reject,并携带失败的配
|
||||
|
||||
Loader 并发挂载各个条目,因此当其他环节失败时,某个界面可能已经持有终端:此时不经过整棵树自身的拆卸就退出,会把 raw 模式、bracketed paste 和键盘协议残留在用户的 shell 上,而尚未返回的终端查询响应会在下一个提示符处显示为字面文本。配置树失败会经 `boot()` 结算:它先释放部分构建的上下文(从而执行该界面自身的 shutdown),再抛出带标签的 rejection。对于 `boot()` 看不到的 rejection(插件游离的异步工作在挂载期间或挂载完成后失败),持有终端的 bin 会传入 `release`,在提交退出前释放整棵树;`dsh` 在 `boot()` 的 `prepare` 回调中捕获根上下文,而不是取其返回值,使该回调覆盖整个挂载窗口。release 执行期间处理函数保持注册并加闩:被报告的始终是第一个 rejection,后续 rejection(包括拆卸自身的)会被吞掉,而不会变成未捕获错误、在拆卸中途杀死进程。
|
||||
|
||||
`cordis:group` 与 `cordis:include` 一并注册,使一份组装能把一个提供方与它的消费方放进同一个 `isolate` realm。两者都通过宿主的模块管线加载,而非被包含树自身的说明符解析,这正是让本工作区之外的组装——放在 Harness home 下的 agent preset——能够使用 group 行的原因。
|
||||
|
||||
配置中的裸插件 specifier(`@deepseek-ai/dsh-*`、npm 包(package))通过 Cordis Loader 的内部模块 loader 解析。仓库 bin 会安装 Loader 的可选 peer `node-addon-require-builtin`;外部调用方必须提供该组件,或者把插件安装到普通 Node import 解析可以找到的位置。相对 specifier 无需原生 helper,并以配置目录为基准解析。构建后的 `dsh-app-boot` 产物内嵌静态挂载的 Include 实现,但仍将 Loader 保持为外部依赖,因此 include 树与 host 会绑定到同一个 Loader peer。`dsh` 源码启动器还会将 manifest(元数据清单)声明的 workspace 包映射到其 TypeScript 源码;其配置门禁要求每个已交付的原始/Web 裸插件都出现在解析所用 manifest 的 `dependencies` 中。
|
||||
|
||||
此包不包含 loader 钩子,也不提供开发模式接口。[`dsh` 应用](../../../apps/cli/README.md)持有自己的 Node 源码启动钩子,并在启动序列中使用这些 helper;构建后的消费方仍使用普通 Node 包解析。
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
"js-yaml": "^4.2.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@cordisjs/plugin-group": "^1.0.0",
|
||||
"@cordisjs/plugin-hmr": "^1.0.15",
|
||||
"@cordisjs/plugin-include": "^1.0.4",
|
||||
"@cordisjs/plugin-loader": "^1.0.0-rc.5",
|
||||
@@ -42,6 +43,7 @@
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@cordisjs/plugin-group": "workspace:^",
|
||||
"@cordisjs/plugin-hmr": "workspace:^",
|
||||
"@cordisjs/plugin-include": "workspace:^",
|
||||
"@cordisjs/plugin-loader": "workspace:^",
|
||||
|
||||
@@ -13,6 +13,7 @@ import * as yaml from 'js-yaml'
|
||||
import { Context, type FiberState } from 'cordis'
|
||||
import Loader, { type Entry, type EntryOptions } from '@cordisjs/plugin-loader'
|
||||
import Include, { applyEntryPatches, entryListSchema, type PatchOptions } from '@cordisjs/plugin-include'
|
||||
import Group from '@cordisjs/plugin-group'
|
||||
import { dshHomePath } from '@deepseek-ai/dsh-paths'
|
||||
import type {} from '@cordisjs/plugin-hmr'
|
||||
// Side-effect type import: resolves `ctx.get('systemPrompt')` to the service.
|
||||
@@ -376,6 +377,12 @@ export async function mountRootInclude(
|
||||
patches: readonly PatchOptions[] = [],
|
||||
): Promise<Entry | undefined> {
|
||||
ctx.loader.builtins.include = Include
|
||||
// `cordis:group` alongside it: a group row is how a composition gives one
|
||||
// `isolate` realm to a provider and its consumers together, and an agent
|
||||
// preset living outside this workspace cannot resolve `@cordisjs/plugin-group`
|
||||
// by name. Both builtins load through the ambient module pipeline, so neither
|
||||
// depends on the included tree's own specifier resolution.
|
||||
ctx.loader.builtins.group = Group
|
||||
// Pinned id: the bootstrap include is app glue, not a config row, and its
|
||||
// id appears in Loader failure chains — a random id would make startup
|
||||
// diagnostics unstable across runs (and snapshot fixtures).
|
||||
|
||||
@@ -8,9 +8,8 @@ import { mkdtempSync, writeFileSync } from 'node:fs'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join } from 'node:path'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import type { Context } from 'cordis'
|
||||
import { Context } from 'cordis'
|
||||
import type { Include } from '@cordisjs/plugin-include'
|
||||
import { Group } from '@cordisjs/plugin-loader'
|
||||
import { boot } from '../src/index.ts'
|
||||
|
||||
const NAME = 'dsh-test-bin'
|
||||
@@ -219,8 +218,10 @@ describe('loader tree replacement', () => {
|
||||
})
|
||||
|
||||
it('stops and restores descendants when an ancestor group is disabled and re-enabled', async () => {
|
||||
// No manual builtin registration: `boot()` supplies `cordis:group` beside
|
||||
// `cordis:include`, which is what lets a composition give one `isolate`
|
||||
// realm to a provider and its consumers together.
|
||||
const { ctx, dir, include } = await bootTree('- id: noop\n name: ./noop.mjs\n')
|
||||
ctx.loader.builtins.group = Group
|
||||
try {
|
||||
const config = (disabled: boolean) => [
|
||||
'- id: parent',
|
||||
@@ -253,7 +254,6 @@ describe('loader tree replacement', () => {
|
||||
const { ctx } = await bootTree('- id: noop\n name: ./noop.mjs\n', {
|
||||
'movable.mjs': plugin('movablePlugin', 'if (config.fail) throw new Error("candidate config failed")'),
|
||||
})
|
||||
ctx.loader.builtins.group = Group
|
||||
try {
|
||||
const groupId = await ctx.loader.create({ name: 'cordis:group', group: true, config: [] })
|
||||
const targetId = await ctx.loader.create({ name: './movable.mjs', config: { fail: false } })
|
||||
@@ -386,3 +386,46 @@ describe('include patches layered over one base', () => {
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe('shipped builtins', () => {
|
||||
it('lets a booted composition share one isolate realm across a group of rows', async () => {
|
||||
// The reason `boot()` registers `cordis:group`: a composition — notably an
|
||||
// agent preset living outside this workspace, which cannot resolve
|
||||
// `@cordisjs/plugin-group` by name — gives a provider and its consumer one
|
||||
// named realm so the service stays out of the root realm while remaining
|
||||
// visible to the rows that need it.
|
||||
const { ctx } = await bootTree([
|
||||
'- id: realm',
|
||||
' name: cordis:group',
|
||||
' isolate:',
|
||||
' demoRealmSvc: true',
|
||||
' config:',
|
||||
' - id: provider',
|
||||
' name: ./provider.mjs',
|
||||
' - id: consumer',
|
||||
' name: ./consumer.mjs',
|
||||
'',
|
||||
].join('\n'), {
|
||||
'provider.mjs': 'export const name = "provider"\n'
|
||||
+ 'export function apply(ctx) { ctx.effect(() => ctx.reflect.provide("demoRealmSvc", { tag: "realm" })) }\n',
|
||||
'consumer.mjs': 'export const name = "consumer"\n'
|
||||
+ 'export const inject = ["demoRealmSvc"]\n'
|
||||
+ 'export function apply(ctx) { globalThis.__REALM_SEEN__ = ctx.get("demoRealmSvc").tag }\n',
|
||||
})
|
||||
try {
|
||||
expect((globalThis as { __REALM_SEEN__?: string }).__REALM_SEEN__).toBe('realm')
|
||||
// `provide` mints the root symbol unconditionally (cordis `reflect.ts`),
|
||||
// so the name IS in the root realm — pinned here because it is the half
|
||||
// that looks like the claim and is not. The claim is the other half: no
|
||||
// implementation is stored under that symbol, so the root realm cannot
|
||||
// resolve the service and a second composition mounting the same rows
|
||||
// cannot collide with this one.
|
||||
const rootKey = ctx.root[Context.isolate].demoRealmSvc
|
||||
expect(rootKey).toBeDefined()
|
||||
expect(ctx.reflect.store[rootKey!]).toBeUndefined()
|
||||
} finally {
|
||||
delete (globalThis as { __REALM_SEEN__?: string }).__REALM_SEEN__
|
||||
await ctx.fiber.dispose()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
{
|
||||
"path": "../../../vendor/include"
|
||||
},
|
||||
{
|
||||
"path": "../../../vendor/group"
|
||||
},
|
||||
{
|
||||
"path": "../../../vendor/hmr"
|
||||
},
|
||||
|
||||
6
pnpm-lock.yaml
generated
6
pnpm-lock.yaml
generated
@@ -5975,6 +5975,9 @@ importers:
|
||||
specifier: ^4.2.0
|
||||
version: 4.2.0
|
||||
devDependencies:
|
||||
'@cordisjs/plugin-group':
|
||||
specifier: workspace:^
|
||||
version: link:../../../vendor/group
|
||||
'@cordisjs/plugin-hmr':
|
||||
specifier: workspace:^
|
||||
version: link:../../../vendor/hmr
|
||||
@@ -6570,6 +6573,9 @@ importers:
|
||||
|
||||
python/sdk-runtime:
|
||||
dependencies:
|
||||
'@cordisjs/plugin-group':
|
||||
specifier: workspace:^
|
||||
version: link:../../vendor/group
|
||||
'@cordisjs/plugin-include':
|
||||
specifier: workspace:^
|
||||
version: link:../../vendor/include
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@cordisjs/plugin-group": "workspace:^",
|
||||
"@cordisjs/plugin-include": "workspace:^",
|
||||
"@cordisjs/plugin-loader": "workspace:^",
|
||||
"@cordisjs/plugin-timer": "workspace:^",
|
||||
|
||||
Reference in New Issue
Block a user