refactor: apply repository naming contract
Apply the accepted pre-release package, service, type, directory, and role renames as one repository-wide change.
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 packages/examples/agent-spine-demo/README.md
|
||||
README.md: 789715e53038f610d1e2db79cf56f9aabd681fac
|
||||
README.zh.md: 7a861297d76d18d5e55539334ca8e7ee5ffef640
|
||||
README.md: 2d48b65e5b5cf08d62bac8b07967965fe38bdd77
|
||||
README.zh.md: 83df672b540649f58b112a08ba0792ca2cb72295
|
||||
|
||||
@@ -18,13 +18,13 @@ Read this package for the whole plugin tree and its composition order.
|
||||
@deepseek-ai/dsh-system-prompt prompt-section + tool-schema assembly
|
||||
@deepseek-ai/dsh-tools registry + guarded pre/around/post/final-result pipeline
|
||||
@deepseek-ai/dsh-skill skill provider registry
|
||||
@deepseek-ai/dsh-skill-local local filesystem skill provider
|
||||
@deepseek-ai/dsh-skill-filesystem local filesystem skill provider
|
||||
@deepseek-ai/dsh-agent agent registry + initiator scope + agent/* events
|
||||
@deepseek-ai/dsh-goal optional persisted same-session goal domain
|
||||
@deepseek-ai/dsh-tool-goal optional model-facing goal controls
|
||||
@deepseek-ai/dsh-goal-session optional same-session goal-round driver
|
||||
@deepseek-ai/dsh-goal-round-driver optional same-session goal-round driver
|
||||
@deepseek-ai/dsh-llm-retry provider-routed request retry policy
|
||||
@deepseek-ai/dsh-tasks-local generic background-task registry
|
||||
@deepseek-ai/dsh-jobs-local generic background-job registry
|
||||
@deepseek-ai/dsh-invariants configurable invariant registry service
|
||||
@deepseek-ai/dsh-session/invariant
|
||||
@deepseek-ai/dsh-agent/invariant
|
||||
@@ -32,9 +32,9 @@ Read this package for the whole plugin tree and its composition order.
|
||||
@deepseek-ai/dsh-agent-loop/invariant
|
||||
package-owned relational checks
|
||||
@deepseek-ai/dsh-tool-bash the model-facing bash schema (unless toolBash=false)
|
||||
@deepseek-ai/dsh-workspace-context AGENTS.md/CLAUDE.md workspace context loader
|
||||
@deepseek-ai/dsh-agent-instructions AGENTS.md/CLAUDE.md workspace context loader
|
||||
@deepseek-ai/dsh-tool-skill session-prefix skill catalog + model-facing loader schema
|
||||
@deepseek-ai/dsh-tool-tasks task_output/task_list/task_kill schemas + completion notices
|
||||
@deepseek-ai/dsh-tool-jobs job_output/job_list/job_kill schemas + completion notices
|
||||
@deepseek-ai/dsh-agent-loop THE concrete loop (gets the forwarded `agents`)
|
||||
(dsh-system-prompt gets the forwarded `persona`)
|
||||
```
|
||||
@@ -44,8 +44,8 @@ Read this package for the whole plugin tree and its composition order.
|
||||
The spine is everything COMMON to every entry point. The swappable and entry-point-coupled pieces stay out, picked by whatever loads the bundle:
|
||||
|
||||
- **the LLM adapter** — the bundle ships the abstract `llm` service; the leaf registers a concrete adapter on `ctx.llm` (`llm-deepseek`, `llm-pi-ai`, `llm-replay`).
|
||||
- **model-backed session-title providers** — the bundle mounts the fallback service with overridable example limits (5 words, 40 fallback bytes, 80 accepted-title bytes); a leaf may opt into exactly one first-message or all-messages LLM provider.
|
||||
- **the bash executor** — the bundle ships `tool-bash` (the consumer schema); the leaf provides `ctx.bash` (`bash-local` or a sandboxed impl).
|
||||
- **model-backed session-title providers** — the bundle mounts the fallback service with overridable example limits (5 words, 40 fallback bytes, 80 accepted-title bytes); a leaf may opt into exactly one first-prompt or all-messages LLM provider.
|
||||
- **the bash executor** — the bundle ships `tool-bash` (the consumer schema); the leaf provides `ctx.shell` (`bash-local` or a sandboxed impl).
|
||||
- **non-local skill providers** — the bundle ships the skill registry, the local filesystem provider, and the `skill` tool; deployments can add other providers such as embedded or remote catalogs as siblings.
|
||||
- **entry point + per-app infrastructure** — headless, ACP, and JSON-RPC app packages own transport, stdout, and reload choices. `timer` stays in the spine because it is common and stdout-silent.
|
||||
|
||||
@@ -55,13 +55,13 @@ This applies the [Service Definition / Service provider / Consumer separation](.
|
||||
|
||||
```ts
|
||||
import type { Config } from '@deepseek-ai/dsh-agent-spine-demo'
|
||||
// { agents?, maxParallelToolCalls?, includeHarnessIdentity?, persona?, toolOrder?, tools?, dshHome?, sessionTitle?, skills?, workspaceContext, toolBash?, tasks?, toolTasks?, goals?, invariants? }
|
||||
// { agents?, maxParallelToolCalls?, includeHarnessIdentity?, persona?, toolOrder?, tools?, dshHome?, sessionTitle?, skills?, workspaceContext, toolBash?, jobs?, toolJobs?, goals?, invariants? }
|
||||
// workspaceContext requires { maxBytes } or false; the other owner schemas supply defaults.
|
||||
```
|
||||
|
||||
The bundle forwards each field to the child that owns it. App packages supply any pre-created agents: headless and JSON-RPC compositions create `main`, while the ACP app creates agents on demand at `session/new`. Prompt, tool, title, skill, workspace-context, invariant, goal, and task settings retain the schemas and defaults documented by their owning packages; `tasks.maxConcurrentTasksPerOwner` configures the local provider independently of the model-facing `toolTasks` controls. `pickSpineConfig()` copies only fields owned by this bundle, and conflicting `dshHome` values fail during composition.
|
||||
The bundle forwards each field to the child that owns it. App packages supply any pre-created agents: headless and JSON-RPC compositions create `main`, while the ACP app creates agents on demand at `session/new`. Prompt, tool, title, skill, agent-instructions, invariant, goal, and task settings retain the schemas and defaults documented by their owning packages; `jobs.maxConcurrentJobsPerOwner` configures the local provider independently of the model-facing `toolJobs` controls. `pickSpineConfig()` copies only fields owned by this bundle, and conflicting `dshHome` values fail during composition.
|
||||
|
||||
For example, `{ invariants: { enabled: true, package_allowlist: ['^@deepseek-ai/dsh-'], package_blocklist: ['agent-loop$'] } }` keeps the package-owned companions mounted but suppresses the blocked owner. Blocklist matches override allowlist matches; see [`dsh-invariants`](../../support/invariants/README.md) for regex and lifecycle rules.
|
||||
For example, `{ invariants: { enabled: true, package_allowlist: ['^@deepseek-ai/dsh-'], package_blocklist: ['agent-loop$'] } }` keeps the package-owned companions mounted but suppresses the blocked owner. Blocklist matches override allowlist matches; see [`dsh-invariants`](../../runtime-diagnostics/invariants/README.md) for regex and lifecycle rules.
|
||||
|
||||
## Why a code bundle, not a shared YAML include
|
||||
|
||||
|
||||
@@ -18,13 +18,13 @@
|
||||
@deepseek-ai/dsh-system-prompt prompt-section + tool-schema assembly
|
||||
@deepseek-ai/dsh-tools registry + guarded pre/around/post/final-result pipeline
|
||||
@deepseek-ai/dsh-skill skill provider registry
|
||||
@deepseek-ai/dsh-skill-local local filesystem skill provider
|
||||
@deepseek-ai/dsh-skill-filesystem local filesystem skill provider
|
||||
@deepseek-ai/dsh-agent agent registry + initiator scope + agent/* events
|
||||
@deepseek-ai/dsh-goal optional persisted same-session goal domain
|
||||
@deepseek-ai/dsh-tool-goal optional model-facing goal controls
|
||||
@deepseek-ai/dsh-goal-session optional same-session goal-round driver
|
||||
@deepseek-ai/dsh-goal-round-driver optional same-session goal-round driver
|
||||
@deepseek-ai/dsh-llm-retry provider-routed request retry policy
|
||||
@deepseek-ai/dsh-tasks-local generic background-task registry
|
||||
@deepseek-ai/dsh-jobs-local generic background-job registry
|
||||
@deepseek-ai/dsh-invariants configurable invariant registry service
|
||||
@deepseek-ai/dsh-session/invariant
|
||||
@deepseek-ai/dsh-agent/invariant
|
||||
@@ -32,9 +32,9 @@
|
||||
@deepseek-ai/dsh-agent-loop/invariant
|
||||
package-owned relational checks
|
||||
@deepseek-ai/dsh-tool-bash the model-facing bash schema (unless toolBash=false)
|
||||
@deepseek-ai/dsh-workspace-context AGENTS.md/CLAUDE.md workspace context loader
|
||||
@deepseek-ai/dsh-agent-instructions AGENTS.md/CLAUDE.md workspace context loader
|
||||
@deepseek-ai/dsh-tool-skill session-prefix skill catalog + model-facing loader schema
|
||||
@deepseek-ai/dsh-tool-tasks task_output/task_list/task_kill schemas + completion notices
|
||||
@deepseek-ai/dsh-tool-jobs job_output/job_list/job_kill schemas + completion notices
|
||||
@deepseek-ai/dsh-agent-loop THE concrete loop (gets the forwarded `agents`)
|
||||
(dsh-system-prompt gets the forwarded `persona`)
|
||||
```
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
- **LLM(大语言模型)适配器**:组合包交付抽象 `llm` 服务;叶节点在 `ctx.llm` 上注册具体适配器(`llm-deepseek`、`llm-pi-ai`、`llm-replay`)。
|
||||
- **基于模型的会话标题提供方**:组合包挂载带可覆盖示例限制的后备服务(5 个词、40 个后备字节、80 个可接受标题字节);叶节点可以恰好选用一个首消息或全消息 LLM 提供方。
|
||||
- **bash 执行器**:组合包交付 `tool-bash`(消费方 schema);叶节点提供 `ctx.bash`(`bash-local` 或沙箱化实现)。
|
||||
- **bash 执行器**:组合包交付 `tool-bash`(消费方 schema);叶节点提供 `ctx.shell`(`bash-local` 或沙箱化实现)。
|
||||
- **非本地 skill 提供方**:组合包交付 skill 注册表、本地文件系统提供方和 `skill` 工具;部署可以把嵌入式目录或远程目录等其他提供方作为同级插件添加。
|
||||
- **入口与各应用基础设施**:无头、ACP(Agent Client Protocol)和 JSON-RPC 应用包负责传输、stdout 与重新加载选择。`timer` 保留在主干中,因为它是共有组件且不写 stdout。
|
||||
|
||||
@@ -55,13 +55,13 @@
|
||||
|
||||
```ts
|
||||
import type { Config } from '@deepseek-ai/dsh-agent-spine-demo'
|
||||
// { agents?, maxParallelToolCalls?, includeHarnessIdentity?, persona?, toolOrder?, tools?, dshHome?, sessionTitle?, skills?, workspaceContext, toolBash?, tasks?, toolTasks?, goals?, invariants? }
|
||||
// { agents?, maxParallelToolCalls?, includeHarnessIdentity?, persona?, toolOrder?, tools?, dshHome?, sessionTitle?, skills?, workspaceContext, toolBash?, jobs?, toolJobs?, goals?, invariants? }
|
||||
// workspaceContext requires { maxBytes } or false; the other owner schemas supply defaults.
|
||||
```
|
||||
|
||||
组合包将每个字段转发给拥有它的子节点。应用包提供预创建的 agent:无头和 JSON-RPC 组合会创建 `main`,ACP 应用则在 `session/new` 按需创建 agent。提示词、工具、标题、skill、工作区上下文、不变式、目标和任务设置沿用其所属包记录的 schema 与默认值;`tasks.maxConcurrentTasksPerOwner` 配置本地 Service provider,并与面向模型的 `toolTasks` 控制工具相互独立。`pickSpineConfig()` 只复制该组合包拥有的字段,`dshHome` 值冲突会在组合时失败。
|
||||
组合包将每个字段转发给拥有它的子节点。应用包提供预创建的 agent:无头和 JSON-RPC 组合会创建 `main`,ACP 应用则在 `session/new` 按需创建 agent。提示词、工具、标题、skill、工作区上下文、不变式、目标和任务设置沿用其所属包记录的 schema 与默认值;`jobs.maxConcurrentJobsPerOwner` 配置本地 Service provider,并与面向模型的 `toolJobs` 控制工具相互独立。`pickSpineConfig()` 只复制该组合包拥有的字段,`dshHome` 值冲突会在组合时失败。
|
||||
|
||||
例如,`{ invariants: { enabled: true, package_allowlist: ['^@deepseek-ai/dsh-'], package_blocklist: ['agent-loop$'] } }` 会让包拥有的配套插件保持挂载,但抑制被阻止的拥有者。Blocklist 匹配优先于 allowlist 匹配;正则表达式与生命周期规则见 [`dsh-invariants`](../../support/invariants/README.md)。
|
||||
例如,`{ invariants: { enabled: true, package_allowlist: ['^@deepseek-ai/dsh-'], package_blocklist: ['agent-loop$'] } }` 会让包拥有的配套插件保持挂载,但抑制被阻止的拥有者。Blocklist 匹配优先于 allowlist 匹配;正则表达式与生命周期规则见 [`dsh-invariants`](../../runtime-diagnostics/invariants/README.md)。
|
||||
|
||||
## 为何使用代码组合包,而非共享 YAML include
|
||||
|
||||
|
||||
@@ -36,42 +36,42 @@
|
||||
"@deepseek-ai/dsh-agent": "workspace:^",
|
||||
"@deepseek-ai/dsh-agent-loop": "workspace:^",
|
||||
"@deepseek-ai/dsh-goal": "workspace:^",
|
||||
"@deepseek-ai/dsh-goal-session": "workspace:^",
|
||||
"@deepseek-ai/dsh-goal-round-driver": "workspace:^",
|
||||
"@deepseek-ai/dsh-invariants": "workspace:^",
|
||||
"@deepseek-ai/dsh-llm": "workspace:^",
|
||||
"@deepseek-ai/dsh-paths": "workspace:^",
|
||||
"@deepseek-ai/dsh-home-paths": "workspace:^",
|
||||
"@deepseek-ai/dsh-llm-retry": "workspace:^",
|
||||
"@deepseek-ai/dsh-scope": "workspace:^",
|
||||
"@deepseek-ai/dsh-session": "workspace:^",
|
||||
"@deepseek-ai/dsh-session-title": "workspace:^",
|
||||
"@deepseek-ai/dsh-skill": "workspace:^",
|
||||
"@deepseek-ai/dsh-skill-local": "workspace:^",
|
||||
"@deepseek-ai/dsh-skill-filesystem": "workspace:^",
|
||||
"@deepseek-ai/dsh-system-prompt": "workspace:^",
|
||||
"@deepseek-ai/dsh-tasks-local": "workspace:^",
|
||||
"@deepseek-ai/dsh-bash-env": "workspace:^",
|
||||
"@deepseek-ai/dsh-jobs-local": "workspace:^",
|
||||
"@deepseek-ai/dsh-shell-env": "workspace:^",
|
||||
"@deepseek-ai/dsh-tool-bash": "workspace:^",
|
||||
"@deepseek-ai/dsh-tool-goal": "workspace:^",
|
||||
"@deepseek-ai/dsh-tool-skill": "workspace:^",
|
||||
"@deepseek-ai/dsh-tool-tasks": "workspace:^",
|
||||
"@deepseek-ai/dsh-tool-jobs": "workspace:^",
|
||||
"@deepseek-ai/dsh-tools": "workspace:^",
|
||||
"@deepseek-ai/dsh-workspace-context": "workspace:^",
|
||||
"@deepseek-ai/dsh-agent-instructions": "workspace:^",
|
||||
"@deepseek-ai/cordis": "workspace:^"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@deepseek-ai/cordis-plugin-timer": "workspace:^",
|
||||
"@deepseek-ai/dsh-agent": "workspace:^",
|
||||
"@deepseek-ai/dsh-agent-loop": "workspace:^",
|
||||
"@deepseek-ai/dsh-bash-env": "workspace:^",
|
||||
"@deepseek-ai/dsh-shell-env": "workspace:^",
|
||||
"@deepseek-ai/dsh-bash-local": "workspace:^",
|
||||
"@deepseek-ai/dsh-bash-sandbox": "workspace:^",
|
||||
"@deepseek-ai/dsh-fs-local": "workspace:^",
|
||||
"@deepseek-ai/dsh-fs-policy": "workspace:^",
|
||||
"@deepseek-ai/dsh-fs-observation-policy": "workspace:^",
|
||||
"@deepseek-ai/dsh-fs-sandbox": "workspace:^",
|
||||
"@deepseek-ai/dsh-goal": "workspace:^",
|
||||
"@deepseek-ai/dsh-goal-session": "workspace:^",
|
||||
"@deepseek-ai/dsh-goal-round-driver": "workspace:^",
|
||||
"@deepseek-ai/dsh-invariants": "workspace:^",
|
||||
"@deepseek-ai/dsh-llm": "workspace:^",
|
||||
"@deepseek-ai/dsh-paths": "workspace:^",
|
||||
"@deepseek-ai/dsh-home-paths": "workspace:^",
|
||||
"@deepseek-ai/dsh-llm-retry": "workspace:^",
|
||||
"@deepseek-ai/dsh-subprocess-local": "workspace:^",
|
||||
"@deepseek-ai/dsh-sandbox-local": "workspace:^",
|
||||
@@ -80,17 +80,17 @@
|
||||
"@deepseek-ai/dsh-session": "workspace:^",
|
||||
"@deepseek-ai/dsh-session-title": "workspace:^",
|
||||
"@deepseek-ai/dsh-skill": "workspace:^",
|
||||
"@deepseek-ai/dsh-skill-local": "workspace:^",
|
||||
"@deepseek-ai/dsh-skill-filesystem": "workspace:^",
|
||||
"@deepseek-ai/dsh-system-prompt": "workspace:^",
|
||||
"@deepseek-ai/dsh-tasks": "workspace:^",
|
||||
"@deepseek-ai/dsh-tasks-local": "workspace:^",
|
||||
"@deepseek-ai/dsh-jobs": "workspace:^",
|
||||
"@deepseek-ai/dsh-jobs-local": "workspace:^",
|
||||
"@deepseek-ai/dsh-tool-bash": "workspace:^",
|
||||
"@deepseek-ai/dsh-tool-fs": "workspace:^",
|
||||
"@deepseek-ai/dsh-tool-goal": "workspace:^",
|
||||
"@deepseek-ai/dsh-tool-skill": "workspace:^",
|
||||
"@deepseek-ai/dsh-tool-tasks": "workspace:^",
|
||||
"@deepseek-ai/dsh-tool-jobs": "workspace:^",
|
||||
"@deepseek-ai/dsh-tools": "workspace:^",
|
||||
"@deepseek-ai/dsh-workspace-context": "workspace:^",
|
||||
"@deepseek-ai/dsh-agent-instructions": "workspace:^",
|
||||
"@deepseek-ai/node-addon-landlock-run": "workspace:*",
|
||||
"@deepseek-ai/cordis": "workspace:^"
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Default executor-less, UI-less agent spine. It bundles the common services,
|
||||
* background-task registry and controls, optional persisted goals, concrete loop, local skill and
|
||||
* workspace-context providers, and model-facing bash/skill consumers;
|
||||
* background-job registry and controls, optional persisted goals, concrete loop, local skill and
|
||||
* agent-instructions providers, and model-facing shell/skill consumers;
|
||||
* deployments still choose the LLM adapter, bash executor, and presentation.
|
||||
* The plugin intentionally exposes named exports only because Loader default
|
||||
* unwrapping would discard its `Config` schema (see docs/postmortem/0001).
|
||||
@@ -11,31 +11,31 @@
|
||||
import type { Context } from '@deepseek-ai/cordis'
|
||||
import Timer from '@deepseek-ai/cordis-plugin-timer'
|
||||
import z from '@deepseek-ai/schemastery'
|
||||
import LlmService from '@deepseek-ai/dsh-llm'
|
||||
import LlmRuntime from '@deepseek-ai/dsh-llm'
|
||||
import SessionStore from '@deepseek-ai/dsh-session'
|
||||
import SessionTitleService, { type Config as SessionTitleConfig } from '@deepseek-ai/dsh-session-title'
|
||||
import SystemPrompt, { type Config as SystemPromptConfig } from '@deepseek-ai/dsh-system-prompt'
|
||||
import ToolRegistry, { type Config as ToolsConfig } from '@deepseek-ai/dsh-tools'
|
||||
import SkillService, { type Config as SkillRegistryConfig } from '@deepseek-ai/dsh-skill'
|
||||
import * as SkillLocal from '@deepseek-ai/dsh-skill-local'
|
||||
import ToolRuntime, { type Config as ToolsConfig } from '@deepseek-ai/dsh-tools'
|
||||
import SkillRegistry, { type Config as SkillRegistryConfig } from '@deepseek-ai/dsh-skill'
|
||||
import * as SkillFileSystem from '@deepseek-ai/dsh-skill-filesystem'
|
||||
import AgentRegistry from '@deepseek-ai/dsh-agent'
|
||||
import GoalService, { type Config as GoalDomainConfig } from '@deepseek-ai/dsh-goal'
|
||||
import * as goalSession from '@deepseek-ai/dsh-goal-session'
|
||||
import * as goalSession from '@deepseek-ai/dsh-goal-round-driver'
|
||||
import * as toolGoal from '@deepseek-ai/dsh-tool-goal'
|
||||
import LocalTaskService, { type Config as TasksConfig } from '@deepseek-ai/dsh-tasks-local'
|
||||
import InvariantService, { type Config as InvariantConfig } from '@deepseek-ai/dsh-invariants'
|
||||
import LocalJobRegistry, { type Config as JobsConfig } from '@deepseek-ai/dsh-jobs-local'
|
||||
import InvariantRegistry, { type Config as InvariantConfig } from '@deepseek-ai/dsh-invariants'
|
||||
import * as sessionInvariant from '@deepseek-ai/dsh-session/invariant'
|
||||
import * as agentInvariant from '@deepseek-ai/dsh-agent/invariant'
|
||||
import * as scopeInvariant from '@deepseek-ai/dsh-scope/invariant'
|
||||
import * as agentLoopInvariant from '@deepseek-ai/dsh-agent-loop/invariant'
|
||||
import * as toolBash from '@deepseek-ai/dsh-tool-bash'
|
||||
import * as bashEnv from '@deepseek-ai/dsh-bash-env'
|
||||
import * as workspaceContext from '@deepseek-ai/dsh-workspace-context'
|
||||
import * as bashEnv from '@deepseek-ai/dsh-shell-env'
|
||||
import * as workspaceContext from '@deepseek-ai/dsh-agent-instructions'
|
||||
import * as toolSkill from '@deepseek-ai/dsh-tool-skill'
|
||||
import * as toolTasks from '@deepseek-ai/dsh-tool-tasks'
|
||||
import * as toolJobs from '@deepseek-ai/dsh-tool-jobs'
|
||||
import AgentLoop, { type Config as AgentLoopConfig } from '@deepseek-ai/dsh-agent-loop'
|
||||
import * as llmRetry from '@deepseek-ai/dsh-llm-retry'
|
||||
import { resolveDshHome } from '@deepseek-ai/dsh-paths'
|
||||
import { resolveDshHome } from '@deepseek-ai/dsh-home-paths'
|
||||
|
||||
export const name = 'agent-spine-demo'
|
||||
|
||||
@@ -53,7 +53,7 @@ export interface SkillConfig {
|
||||
/** Registry-level discovery cache settings. */
|
||||
registry?: SkillRegistryConfig
|
||||
/** Local filesystem skill provider settings. */
|
||||
local?: SkillLocal.Config
|
||||
filesystem?: SkillFileSystem.Config
|
||||
/** Model-facing skill catalog and tool settings. */
|
||||
tool?: toolSkill.Config
|
||||
}
|
||||
@@ -75,8 +75,8 @@ export interface GoalConfig {
|
||||
* `dshHome` to bash environment and local skill discovery, `sessionTitle` to
|
||||
* the fallback title service, `skills` to the
|
||||
* skill registry/local provider/tool consumer, `workspaceContext` to the
|
||||
* workspace-context loader, `tasks` to the process-local task provider, and
|
||||
* `toolBash`/`toolTasks` to the model-facing tool plugins this bundle owns.
|
||||
* agent-instructions loader, `jobs` to the process-local job provider, and
|
||||
* `toolBash`/`toolJobs` to the model-facing tool plugins this bundle owns.
|
||||
* Provider adapters own their `retryPolicy`; this bundle always mounts its
|
||||
* executor.
|
||||
* `goals` opts into and configures the persisted goal domain plus its model tool
|
||||
@@ -115,10 +115,10 @@ export interface Config {
|
||||
skills?: SkillConfig
|
||||
/** Model-facing bash tool config, or false when another plugin owns `bash`. */
|
||||
toolBash?: toolBash.Config | false
|
||||
/** Process-local background-task admission config. */
|
||||
tasks?: TasksConfig
|
||||
/** Generic background-task controls; set false to keep the task service without model-facing task tools. */
|
||||
toolTasks?: toolTasks.Config | false
|
||||
/** Process-local background-job admission config. */
|
||||
jobs?: JobsConfig
|
||||
/** Generic background-job controls; set false to keep the job service without model-facing job tools. */
|
||||
toolJobs?: toolJobs.Config | false
|
||||
/** Global enablement and package-name filters for invariant companions. */
|
||||
invariants?: InvariantConfig
|
||||
/** Opt-in persisted same-session goal stack; set false or omit to leave it unmounted. */
|
||||
@@ -128,8 +128,8 @@ export interface Config {
|
||||
/** The skill config schema exported for app packages that forward `skills`. */
|
||||
export const SkillConfigSchema: z<SkillConfig> = z.object({
|
||||
enabled: z.boolean().default(true),
|
||||
registry: SkillService.Config,
|
||||
local: SkillLocal.Config,
|
||||
registry: SkillRegistry.Config,
|
||||
filesystem: SkillFileSystem.Config,
|
||||
tool: toolSkill.Config,
|
||||
})
|
||||
|
||||
@@ -141,11 +141,11 @@ export const SessionTitleConfigSchema: z<SessionTitleConfig> = SessionTitleServi
|
||||
export const ToolBashConfigSchema: z<toolBash.Config | false> =
|
||||
z.union([z.const(false), toolBash.Config])
|
||||
|
||||
/** The process-local task registry schema exported for app packages that forward `tasks`. */
|
||||
export const TasksConfigSchema: z<TasksConfig> = LocalTaskService.Config
|
||||
/** The process-local job registry schema exported for app packages that forward `jobs`. */
|
||||
export const JobsConfigSchema: z<JobsConfig> = LocalJobRegistry.Config
|
||||
|
||||
/** The task-control-tool config schema exported for app packages that forward `toolTasks`. */
|
||||
export const ToolTasksConfigSchema: z<toolTasks.Config> = toolTasks.Config
|
||||
/** The job-control-tool config schema exported for app packages that forward `toolJobs`. */
|
||||
export const ToolJobsConfigSchema: z<toolJobs.Config> = toolJobs.Config
|
||||
|
||||
/** The persisted-goal config schema exported for app packages that opt in. */
|
||||
export const GoalConfigSchema: z<GoalConfig> = z.object({
|
||||
@@ -158,17 +158,17 @@ export const Config = z.intersect([
|
||||
AgentLoop.Config,
|
||||
SystemPrompt.Config,
|
||||
z.object({
|
||||
tools: ToolRegistry.Config,
|
||||
tools: ToolRuntime.Config,
|
||||
dshHome: z.string(),
|
||||
sessionTitle: SessionTitleConfigSchema,
|
||||
skills: SkillConfigSchema,
|
||||
workspaceContext: z.union([z.const(false), workspaceContext.Config]).required(),
|
||||
toolBash: ToolBashConfigSchema,
|
||||
tasks: TasksConfigSchema,
|
||||
toolTasks: z.union([z.const(false), ToolTasksConfigSchema]),
|
||||
invariants: InvariantService.Config,
|
||||
jobs: JobsConfigSchema,
|
||||
toolJobs: z.union([z.const(false), ToolJobsConfigSchema]),
|
||||
invariants: InvariantRegistry.Config,
|
||||
goals: z.union([z.const(false), GoalConfigSchema]),
|
||||
}) as unknown as z<Pick<Config, 'tools' | 'dshHome' | 'sessionTitle' | 'skills' | 'workspaceContext' | 'toolBash' | 'tasks' | 'toolTasks' | 'invariants' | 'goals'>>,
|
||||
}) as unknown as z<Pick<Config, 'tools' | 'dshHome' | 'sessionTitle' | 'skills' | 'workspaceContext' | 'toolBash' | 'jobs' | 'toolJobs' | 'invariants' | 'goals'>>,
|
||||
]) as unknown as z<Config>
|
||||
|
||||
/**
|
||||
@@ -188,8 +188,8 @@ export function pickSpineConfig(config: Omit<Config, 'agents'>): Omit<Config, 'a
|
||||
workspaceContext: config.workspaceContext,
|
||||
...config.skills !== undefined ? { skills: config.skills } : {},
|
||||
...config.toolBash !== undefined ? { toolBash: config.toolBash } : {},
|
||||
...config.tasks !== undefined ? { tasks: config.tasks } : {},
|
||||
...config.toolTasks !== undefined ? { toolTasks: config.toolTasks } : {},
|
||||
...config.jobs !== undefined ? { jobs: config.jobs } : {},
|
||||
...config.toolJobs !== undefined ? { toolJobs: config.toolJobs } : {},
|
||||
...config.invariants !== undefined ? { invariants: config.invariants } : {},
|
||||
...config.goals !== undefined ? { goals: config.goals } : {},
|
||||
}
|
||||
@@ -206,15 +206,15 @@ export function pickSpineConfig(config: Omit<Config, 'agents'>): Omit<Config, 'a
|
||||
* seams, then the loop that drives them.
|
||||
*/
|
||||
export function apply(ctx: Context, config: Config): void {
|
||||
const nestedDshHome = config.skills?.local?.dshHome
|
||||
const nestedDshHome = config.skills?.filesystem?.dshHome
|
||||
if (config.dshHome !== undefined && nestedDshHome !== undefined
|
||||
&& resolveDshHome(config.dshHome) !== resolveDshHome(nestedDshHome)) {
|
||||
throw new Error('agent-spine-demo: dshHome and skills.local.dshHome must resolve to the same directory')
|
||||
throw new Error('agent-spine-demo: dshHome and skills.filesystem.dshHome must resolve to the same directory')
|
||||
}
|
||||
const dshHome = resolveDshHome(config.dshHome ?? nestedDshHome)
|
||||
|
||||
ctx.plugin(Timer)
|
||||
ctx.plugin(LlmService)
|
||||
ctx.plugin(LlmRuntime)
|
||||
ctx.plugin(SessionStore)
|
||||
ctx.plugin(SessionTitleService, config.sessionTitle ?? EXAMPLE_SESSION_TITLE_CONFIG)
|
||||
// Owner schemas resolve defaults; forward toolOrder only when explicitly set.
|
||||
@@ -223,11 +223,11 @@ export function apply(ctx: Context, config: Config): void {
|
||||
persona: config.persona ?? '',
|
||||
...config.toolOrder !== undefined ? { toolOrder: config.toolOrder } : {},
|
||||
})
|
||||
ctx.plugin(ToolRegistry, config.tools ?? {})
|
||||
ctx.plugin(ToolRuntime, config.tools ?? {})
|
||||
const skillsEnabled = config.skills?.enabled ?? true
|
||||
if (skillsEnabled) {
|
||||
ctx.plugin(SkillService, config.skills?.registry ?? {})
|
||||
ctx.plugin(SkillLocal, Object.assign({}, config.skills?.local, { dshHome }))
|
||||
ctx.plugin(SkillRegistry, config.skills?.registry ?? {})
|
||||
ctx.plugin(SkillFileSystem, Object.assign({}, config.skills?.filesystem, { dshHome }))
|
||||
}
|
||||
ctx.plugin(AgentRegistry)
|
||||
ctx.plugin(llmRetry)
|
||||
@@ -236,8 +236,8 @@ export function apply(ctx: Context, config: Config): void {
|
||||
ctx.plugin(toolGoal, config.goals.tool ?? {})
|
||||
ctx.plugin(goalSession)
|
||||
}
|
||||
ctx.plugin(LocalTaskService, config.tasks ?? {})
|
||||
ctx.plugin(InvariantService, config.invariants ?? {})
|
||||
ctx.plugin(LocalJobRegistry, config.jobs ?? {})
|
||||
ctx.plugin(InvariantRegistry, config.invariants ?? {})
|
||||
ctx.plugin(sessionInvariant)
|
||||
ctx.plugin(agentInvariant)
|
||||
ctx.plugin(scopeInvariant)
|
||||
@@ -252,7 +252,7 @@ export function apply(ctx: Context, config: Config): void {
|
||||
// Both plugins prepend session-prefix messages. Registration order is the
|
||||
// rendered order, so workspace instructions must precede the skill catalog.
|
||||
if (skillsEnabled) ctx.plugin(toolSkill, config.skills?.tool ?? {})
|
||||
if (config.toolTasks !== false) ctx.plugin(toolTasks, config.toolTasks ?? {})
|
||||
if (config.toolJobs !== false) ctx.plugin(toolJobs, config.toolJobs ?? {})
|
||||
ctx.plugin(AgentLoop, {
|
||||
agents: config.agents ?? [],
|
||||
...config.maxParallelToolCalls !== undefined ? { maxParallelToolCalls: config.maxParallelToolCalls } : {},
|
||||
|
||||
@@ -31,8 +31,8 @@ import * as agentLoopInvariant from '@deepseek-ai/dsh-agent-loop/invariant'
|
||||
|
||||
const testToolSignal = new AbortController().signal
|
||||
|
||||
declare module '@deepseek-ai/dsh-tasks' {
|
||||
interface TaskKindMap {
|
||||
declare module '@deepseek-ai/dsh-jobs' {
|
||||
interface JobKindMap {
|
||||
probe: 'probe'
|
||||
}
|
||||
}
|
||||
@@ -69,7 +69,7 @@ async function mount(config: agentCore.Config, withBash = false): Promise<Contex
|
||||
process.env.DSH_AGENTS_HOME = await mkdtemp(join(tmpdir(), 'dsh-agent-spine-demo-agents-'))
|
||||
const ctx = new Context()
|
||||
if (withBash) {
|
||||
ctx.provide('bash', {
|
||||
ctx.provide('shell', {
|
||||
sandboxMode: undefined,
|
||||
resolve() { throw new Error('composition test does not execute bash') },
|
||||
run() { throw new Error('composition test does not execute bash') },
|
||||
@@ -156,7 +156,7 @@ describe('dsh-agent-spine-demo bundle', () => {
|
||||
expect(ctx.get('tools')).toBeDefined()
|
||||
expect(ctx.get('skills')).toBeDefined()
|
||||
expect(ctx.get('agents')).toBeDefined()
|
||||
expect(ctx.get('tasks')).toBeDefined()
|
||||
expect(ctx.get('jobs')).toBeDefined()
|
||||
expect(ctx.get('invariants')).toBeDefined()
|
||||
expect(ctx.get('agentLoop')).toBeDefined()
|
||||
expect(ctx.get('goals')).toBeUndefined()
|
||||
@@ -302,11 +302,11 @@ describe('dsh-agent-spine-demo bundle', () => {
|
||||
|
||||
it('forwards task admission config to the process-local provider', async () => {
|
||||
const ctx = await mount({
|
||||
tasks: { maxConcurrentTasksPerOwner: 1 },
|
||||
jobs: { maxConcurrentJobsPerOwner: 1 },
|
||||
workspaceContext: false,
|
||||
})
|
||||
let settle!: (outcome: { status: 'killed' }) => void
|
||||
ctx.tasks.start({
|
||||
ctx.jobs.start({
|
||||
kind: 'probe',
|
||||
label: 'hold configured slot',
|
||||
run: () => ({
|
||||
@@ -314,7 +314,7 @@ describe('dsh-agent-spine-demo bundle', () => {
|
||||
done: new Promise((resolve) => { settle = resolve }),
|
||||
}),
|
||||
})
|
||||
expect(() => ctx.tasks.start({
|
||||
expect(() => ctx.jobs.start({
|
||||
kind: 'probe',
|
||||
label: 'blocked configured task',
|
||||
run: () => ({ cancel: () => {}, done: Promise.resolve({ status: 'completed' }) }),
|
||||
@@ -375,7 +375,7 @@ describe('dsh-agent-spine-demo bundle', () => {
|
||||
const firstRequestText = adapter.requests[0]?.messages.map(messageText).join('\n')
|
||||
expect(firstRequestText).toContain('hi')
|
||||
expect(firstRequestText).toContain('bundled project rule')
|
||||
expect(adapter.requests[0]?.system).toContain('You are an AI agent powered by the DeepSeek Harness SDK.')
|
||||
expect(adapter.requests[0]?.system).toContain('You are an AI agent powered by DeepSeek Harness.')
|
||||
expect(adapter.requests[0]?.system).not.toContain('bundled project rule')
|
||||
await handle.dispose()
|
||||
await ctx.fiber.dispose()
|
||||
@@ -384,7 +384,7 @@ describe('dsh-agent-spine-demo bundle', () => {
|
||||
}
|
||||
})
|
||||
|
||||
it('forwards workspace-context config to the bundled loader', async () => {
|
||||
it('forwards agent-instructions config to the bundled loader', async () => {
|
||||
const root = await mkdtemp(join(tmpdir(), 'dsh-agent-spine-demo-workspace-context-disabled-'))
|
||||
try {
|
||||
await mkdir(join(root, '.git'), { recursive: true })
|
||||
@@ -425,7 +425,7 @@ describe('dsh-agent-spine-demo bundle', () => {
|
||||
workspaceContext: false,
|
||||
skills: {
|
||||
registry: { collectCacheMaxEntries: 4 },
|
||||
local: {
|
||||
filesystem: {
|
||||
dshHome: join(home, '.dsh'),
|
||||
agentsHome: join(agentsHome, '.agents'),
|
||||
customSkillDirs: [custom],
|
||||
@@ -460,7 +460,7 @@ describe('dsh-agent-spine-demo bundle', () => {
|
||||
const ctx = await mount({
|
||||
workspaceContext: false,
|
||||
skills: {
|
||||
local: {
|
||||
filesystem: {
|
||||
dshHome: join(home, '.dsh'),
|
||||
agentsHome: join(home, '.agents'),
|
||||
watchStabilityThresholdMs: 20,
|
||||
@@ -598,7 +598,7 @@ describe('dsh-agent-spine-demo bundle', () => {
|
||||
const ctx = await mount({
|
||||
dshHome: home,
|
||||
workspaceContext: false,
|
||||
skills: { local: { agentsHome } },
|
||||
skills: { filesystem: { agentsHome } },
|
||||
}, true)
|
||||
|
||||
expect((await ctx.skills.list()).map(skill => skill.name)).toEqual(['shared-skill'])
|
||||
@@ -610,7 +610,7 @@ describe('dsh-agent-spine-demo bundle', () => {
|
||||
name: 'bash',
|
||||
arguments: { command: 'true' },
|
||||
}
|
||||
expect(ctx.bashEnv.collect(execution)).toMatchObject({ DSH_HOME: home, DSH_SHELL: '1' })
|
||||
expect(ctx.shellEnv.collect(execution)).toMatchObject({ DSH_HOME: home, DSH_SHELL: '1' })
|
||||
await ctx.fiber.dispose()
|
||||
})
|
||||
|
||||
@@ -619,9 +619,9 @@ describe('dsh-agent-spine-demo bundle', () => {
|
||||
agentCore.apply(new Context(), {
|
||||
dshHome: '/global-dsh-home',
|
||||
workspaceContext: false,
|
||||
skills: { local: { dshHome: '/nested-dsh-home' } },
|
||||
skills: { filesystem: { dshHome: '/nested-dsh-home' } },
|
||||
})
|
||||
}).toThrow('agent-spine-demo: dshHome and skills.local.dshHome must resolve to the same directory')
|
||||
}).toThrow('agent-spine-demo: dshHome and skills.filesystem.dshHome must resolve to the same directory')
|
||||
})
|
||||
|
||||
it('delivers workspace instructions ahead of the first-step skill catalog', async () => {
|
||||
@@ -665,11 +665,11 @@ describe('dsh-agent-spine-demo bundle', () => {
|
||||
}
|
||||
})
|
||||
|
||||
it('forwards its bundled tool configs to tool-bash and tool-tasks', async () => {
|
||||
it('forwards its bundled tool configs to tool-bash and tool-jobs', async () => {
|
||||
const ctx = await mount({
|
||||
workspaceContext: false,
|
||||
toolBash: { enableRunInBackground: false },
|
||||
toolTasks: { waitTimeoutMs: 7, maxWaitTimeoutMs: 11 },
|
||||
toolJobs: { waitTimeoutMs: 7, maxWaitTimeoutMs: 11 },
|
||||
}, true)
|
||||
|
||||
const bash = ctx.tools.schemas().find(tool => tool.name === 'bash')
|
||||
@@ -677,17 +677,17 @@ describe('dsh-agent-spine-demo bundle', () => {
|
||||
expect(Object.keys((bash!.parameters as { properties: Record<string, unknown> }).properties))
|
||||
.not.toContain('run_in_background')
|
||||
|
||||
const id = ctx.tasks.start({
|
||||
const id = ctx.jobs.start({
|
||||
kind: 'probe',
|
||||
label: 'config forwarding probe',
|
||||
run: () => ({ cancel: () => {}, done: Promise.resolve({ status: 'completed' }) }),
|
||||
})
|
||||
const wait = vi.spyOn(ctx.tasks, 'wait')
|
||||
const wait = vi.spyOn(ctx.jobs, 'wait')
|
||||
await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('task-config-forwarding'),
|
||||
name: 'task_output',
|
||||
arguments: { task_id: id, wait: true },
|
||||
name: 'job_output',
|
||||
arguments: { job_id: id, wait: true },
|
||||
})
|
||||
expect(wait).toHaveBeenCalledWith(id, 7, undefined, testToolSignal)
|
||||
|
||||
@@ -699,12 +699,12 @@ describe('dsh-agent-spine-demo bundle', () => {
|
||||
workspaceContext: false,
|
||||
skills: { enabled: false },
|
||||
toolBash: { enableRunInBackground: false },
|
||||
toolTasks: false,
|
||||
toolJobs: false,
|
||||
}, true)
|
||||
|
||||
expect(ctx.tools.schemas().map(tool => tool.name)).toEqual(['bash'])
|
||||
expect(ctx.get('skills')).toBeUndefined()
|
||||
expect(ctx.get('tasks')).toBeDefined()
|
||||
expect(ctx.get('jobs')).toBeDefined()
|
||||
|
||||
await ctx.fiber.dispose()
|
||||
})
|
||||
@@ -716,7 +716,7 @@ describe('dsh-agent-spine-demo bundle', () => {
|
||||
workspaceContext: false,
|
||||
skills: { enabled: false },
|
||||
toolBash: false,
|
||||
toolTasks: false,
|
||||
toolJobs: false,
|
||||
}, true)
|
||||
|
||||
expect(ctx.tools.schemas()).toEqual([])
|
||||
@@ -738,8 +738,8 @@ describe('dsh-agent-spine-demo bundle', () => {
|
||||
workspaceContext: false as const,
|
||||
skills: { enabled: false },
|
||||
toolBash: { enableRunInBackground: false },
|
||||
tasks: { maxConcurrentTasksPerOwner: 4 },
|
||||
toolTasks: false as const,
|
||||
jobs: { maxConcurrentJobsPerOwner: 4 },
|
||||
toolJobs: false as const,
|
||||
invariants: { enabled: false },
|
||||
}
|
||||
|
||||
@@ -753,8 +753,8 @@ describe('dsh-agent-spine-demo bundle', () => {
|
||||
workspaceContext: false,
|
||||
skills: appConfig.skills,
|
||||
toolBash: appConfig.toolBash,
|
||||
tasks: appConfig.tasks,
|
||||
toolTasks: appConfig.toolTasks,
|
||||
jobs: appConfig.jobs,
|
||||
toolJobs: appConfig.toolJobs,
|
||||
invariants: appConfig.invariants,
|
||||
})
|
||||
expect(agentCore.pickSpineConfig({ workspaceContext: false })).toEqual({ workspaceContext: false })
|
||||
@@ -773,7 +773,7 @@ describe('dsh-agent-spine-demo bundle', () => {
|
||||
|
||||
it('forwards toolOrder to the system-prompt assembly', async () => {
|
||||
const ctx = await mount({ toolOrder: ['zulu', TOOL_ORDER_REST], workspaceContext: false })
|
||||
// The bundle's own bash tools pend on the absent `ctx.bash` executor in
|
||||
// The bundle's own bash tools pend on the absent `ctx.shell` executor in
|
||||
// this providerless mount, so register two plain tools to order.
|
||||
for (const name of ['alpha', 'zulu']) {
|
||||
ctx.get('tools')!.register({
|
||||
@@ -785,7 +785,7 @@ describe('dsh-agent-spine-demo bundle', () => {
|
||||
})
|
||||
}
|
||||
const assembly = await ctx.get('systemPrompt')!.assemble()
|
||||
expect(assembly.tools.map(tool => tool.name)).toEqual(['zulu', 'alpha', 'skill', 'task_kill', 'task_list', 'task_output'])
|
||||
expect(assembly.tools.map(tool => tool.name)).toEqual(['zulu', 'alpha', 'job_kill', 'job_list', 'job_output', 'skill'])
|
||||
await ctx.fiber.dispose()
|
||||
})
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ import { basename, join } from 'node:path'
|
||||
import { afterEach, beforeEach, describe, expect, it } from 'vitest'
|
||||
import { Context } from '@deepseek-ai/cordis'
|
||||
import { SandboxBashExecutor } from '@deepseek-ai/dsh-bash-sandbox'
|
||||
import LocalSubprocessService from '@deepseek-ai/dsh-subprocess-local'
|
||||
import * as FsPolicy from '@deepseek-ai/dsh-fs-policy'
|
||||
import LocalSubprocessRuntime from '@deepseek-ai/dsh-subprocess-local'
|
||||
import * as FsPolicy from '@deepseek-ai/dsh-fs-observation-policy'
|
||||
import SandboxedFileSystem from '@deepseek-ai/dsh-fs-sandbox'
|
||||
import { CallId } from '@deepseek-ai/dsh-llm'
|
||||
import { LocalSandboxProvider } from '@deepseek-ai/dsh-sandbox-local'
|
||||
@@ -53,14 +53,14 @@ beforeEach(async () => {
|
||||
ctx = new Context()
|
||||
await ctx.plugin(LocalSandboxProvider, {})
|
||||
await ctx.plugin(SandboxPolicyService, { mode: 'workspace-write', workspaceRoot: fallbackRoot })
|
||||
await ctx.plugin(LocalSubprocessService)
|
||||
await ctx.plugin(LocalSubprocessRuntime)
|
||||
await ctx.plugin(SandboxBashExecutor, { cwd: fallbackRoot, timeoutMs: 30_000 })
|
||||
await ctx.plugin(SandboxedFileSystem, { cwd: fallbackRoot })
|
||||
await ctx.plugin(agentSpine, {
|
||||
workspaceContext: false,
|
||||
skills: { enabled: false },
|
||||
toolBash: { enableRunInBackground: false },
|
||||
toolTasks: false,
|
||||
toolJobs: false,
|
||||
})
|
||||
await new Promise(resolve => setTimeout(resolve, 50))
|
||||
await ctx.plugin(FsPolicy)
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
"path": "../../skill/skill"
|
||||
},
|
||||
{
|
||||
"path": "../../skill/skill-local"
|
||||
"path": "../../skill/skill-filesystem"
|
||||
},
|
||||
{
|
||||
"path": "../../skill/tool-skill"
|
||||
@@ -54,10 +54,10 @@
|
||||
"path": "../../goal/tool-goal"
|
||||
},
|
||||
{
|
||||
"path": "../../goal/goal-session"
|
||||
"path": "../../goal/goal-round-driver"
|
||||
},
|
||||
{
|
||||
"path": "../../context/workspace-context"
|
||||
"path": "../../context/agent-instructions"
|
||||
},
|
||||
{
|
||||
"path": "../../core/agent-loop"
|
||||
@@ -66,25 +66,25 @@
|
||||
"path": "../../llm/llm-retry"
|
||||
},
|
||||
{
|
||||
"path": "../../support/invariants"
|
||||
"path": "../../runtime-diagnostics/invariants"
|
||||
},
|
||||
{
|
||||
"path": "../../util/paths"
|
||||
"path": "../../util/home-paths"
|
||||
},
|
||||
{
|
||||
"path": "../../bash/bash-env"
|
||||
"path": "../../shell/shell-env"
|
||||
},
|
||||
{
|
||||
"path": "../../bash/tool-bash"
|
||||
"path": "../../shell/tool-bash"
|
||||
},
|
||||
{
|
||||
"path": "../../tasks/tasks"
|
||||
"path": "../../jobs/jobs"
|
||||
},
|
||||
{
|
||||
"path": "../../tasks/tasks-local"
|
||||
"path": "../../jobs/jobs-local"
|
||||
},
|
||||
{
|
||||
"path": "../../tasks/tool-tasks"
|
||||
"path": "../../jobs/tool-jobs"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user