@shgroup/dsh-serenity-hooks 1.34.0 → 1.34.2
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/README.md +1 -0
- package/dsh.plugin.json +1 -1
- package/lib/acp-core.d.ts +2 -22
- package/lib/acp-http.d.ts +8 -0
- package/lib/api.d.ts +12 -4
- package/lib/autopilot-chain.d.ts +76 -0
- package/lib/autopilot-core-DCRkiWEe.js +229 -0
- package/lib/autopilot-core.d.ts +132 -0
- package/lib/autopilot-ops.d.ts +48 -0
- package/lib/autopilot-trajectory-D9Znxo75.js +782 -0
- package/lib/autopilot-trajectory.d.ts +64 -97
- package/lib/ccc-roots-Bd_SjEs7.js +152 -0
- package/lib/ccc-roots.d.ts +105 -0
- package/lib/ccc.d.ts +3 -6
- package/lib/client.js +2 -2
- package/lib/clock-runtime.d.ts +197 -0
- package/lib/config-ops.d.ts +9 -14
- package/lib/constants.d.ts +0 -2
- package/lib/container-status.d.ts +183 -0
- package/lib/diag-ops.d.ts +25 -10
- package/lib/face-host.d.ts +110 -0
- package/lib/fs-ops.d.ts +3 -2
- package/lib/gateway-auth.d.ts +2 -5
- package/lib/gateway.d.ts +0 -34
- package/lib/git-ops.d.ts +3 -2
- package/lib/handyman-ops.d.ts +3 -2
- package/lib/handyman-preset-inherit.d.ts +2 -1
- package/lib/host/access.d.ts +8 -7
- package/lib/host/contract.d.ts +29 -6
- package/lib/host/type-contract.d.ts +1 -2
- package/lib/im-bridge.d.ts +6 -5
- package/lib/index.js +8336 -5607
- package/lib/invariant.d.ts +0 -15
- package/lib/invariant.js +1 -1
- package/lib/kit-ops.d.ts +11 -31
- package/lib/localstore-ops.d.ts +3 -17
- package/lib/msm-ops.d.ts +34 -52
- package/lib/opencode-provider.d.ts +4 -5
- package/lib/output-guard-seam.d.ts +0 -3
- package/lib/output-guard.d.ts +12 -3
- package/lib/ports.d.ts +59 -0
- package/lib/rebuild.d.ts +1 -1
- package/lib/seams/bootstrap.d.ts +4 -3
- package/lib/seams/compact.d.ts +2 -1
- package/lib/seams/context.d.ts +2 -4
- package/lib/seams/env.d.ts +2 -1
- package/lib/seams/guards.d.ts +4 -43
- package/lib/seams/keeper.d.ts +1 -1
- package/lib/seams/system-prompt.d.ts +1 -5
- package/lib/session-cleanup.d.ts +3 -2
- package/lib/{settings-section-BuPGQv_H.js → settings-section-DTYZjwUs.js} +65 -9
- package/lib/settings-section.d.ts +3 -31
- package/lib/skiff-core.d.ts +4 -9
- package/lib/skiff-debug.d.ts +15 -21
- package/lib/skiff-registry-FTjoWQTQ.js +25 -0
- package/lib/skiff-registry.d.ts +2 -1
- package/lib/{skiff-role-DAfPb6YQ.js → skiff-role-CEHL5cek.js} +1 -1
- package/lib/skiff-role.d.ts +2 -2
- package/lib/skills/opencode-scan.d.ts +3 -2
- package/lib/skills-discovery.d.ts +15 -2
- package/lib/status.d.ts +2 -1
- package/lib/tools/cce.d.ts +1 -2
- package/lib/tools/container-admin.d.ts +7 -3
- package/lib/tools/eap.d.ts +2 -3
- package/lib/tools/handyman.d.ts +0 -29
- package/lib/tools/msm.d.ts +0 -4
- package/lib/tools/neat.d.ts +1 -2
- package/lib/tools/praxis.d.ts +0 -1
- package/lib/tools/skiff-admin.d.ts +2 -2
- package/lib/tools/trajectory.d.ts +7 -15
- package/lib/totp.d.ts +0 -4
- package/lib/trajectory-assistant.d.ts +2 -1
- package/lib/trajectory-bound-Cax1p9ut.js +190 -0
- package/lib/trajectory-bound.d.ts +3 -4
- package/lib/{trajectory-bound-C8DUxi6_.js → trajectory-ops-mrXK0H0I.js} +2 -159
- package/lib/trajectory-ops.d.ts +4 -9
- package/lib/trajectory-skills.d.ts +71 -0
- package/lib/{wake-registry-D0Vj0WXb.js → wake-registry-CYxIb484.js} +7 -20
- package/lib/wake-registry.d.ts +3 -11
- package/lib/wake-scheduler.d.ts +13 -49
- package/lib/web-fetch-provider.d.ts +0 -21
- package/lib/{weixin-api-PjEhmjlZ.js → weixin-api-CtFYm53S.js} +3 -9
- package/lib/weixin-api.d.ts +6 -37
- package/lib/weixin-bridge.d.ts +5 -24
- package/lib/weixin-hook.d.ts +6 -12
- package/lib/weixin-output-guard.d.ts +2 -1
- package/lib/{weixin-route-D1ND823E.js → weixin-route-B2ajFypI.js} +4 -5
- package/lib/weixin-route.d.ts +0 -2
- package/lib/weixin-send-api.d.ts +15 -6
- package/package.json +2 -4
- package/experiments/autopilot-trajectory/SKILL.md +0 -115
- package/experiments/autopilot-trajectory/scripts/autopilot-trajectory.ts +0 -546
- package/lib/autopilot-script.d.ts +0 -40
- package/lib/skiff-debug-D83-Njy7.js +0 -2867
- package/lib/{ccc-eu_IPF94.js → ccc-NlLr_sxy.js} +1 -1
- package/lib/{session-cleanup-CMT4mHWt.js → session-cleanup-B6IHZgww.js} +1 -1
|
@@ -1,546 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bun
|
|
2
|
-
/**
|
|
3
|
-
* autopilot-trajectory.ts — 自主轨迹实验管理脚本(Mech,纯 TS 零 LLM 决策)——一站式
|
|
4
|
-
*
|
|
5
|
-
* 脚本通道(v1.33 命名:CCC 工具面已改由 `container_admin autopilot` 承载**三个**动作,
|
|
6
|
-
* 脚本自身保留全部子命令供开发面直接调用):
|
|
7
|
-
* container_admin autopilot status → 一站式全报告(背景 + 就绪 + 状态 + 下一步) [脚本 all]
|
|
8
|
-
* container_admin autopilot init → 初始化实验(写配置 + 生成偏见提供者脚本模板) [脚本 init]
|
|
9
|
-
* container_admin autopilot generate-bias → 运行偏见提供者脚本,输出当前偏见内容(验证) [脚本 random]
|
|
10
|
-
* (开发面)bun <脚本> diag → 唤起条件链诊断(--ccc <path> 指定;无参递归扫描 /home/yh 两层)
|
|
11
|
-
* (开发面)bun <脚本> doc|check|status|guide → 定义全文 / 仅就绪度 / 仅状态 / 仅步骤指引
|
|
12
|
-
*
|
|
13
|
-
* 概念(用户拍板命名):偏见内容提供者(bias provider)——CCC 根目录下一个脚本,
|
|
14
|
-
* stdout 输出本轮唤起要注入的偏见内容(反事实方向/探索动机等)。tool 直接运行它;
|
|
15
|
-
* 脚本缺失 → 报错要求实现(不再经 mech-registry 注册 MSM)。
|
|
16
|
-
*
|
|
17
|
-
* 状态查看:WebUI 设置面板「trajectory」区块(GET /serenity/trajectory)+「立即唤起」按钮
|
|
18
|
-
* (POST /serenity/trajectory {action:'wake'},调试语义跳过窗口/间隔)——由插件提供,脚本不重复。
|
|
19
|
-
* 运行态诊断(live 会话 / agent 定位 / 唤醒注册表):专属工具 `acc-diag`(ACC 负责人)。
|
|
20
|
-
*
|
|
21
|
-
* 零 DSH 依赖,任何 CCC 可运行。环境:SERENITY_ROOT(由 `container_admin` 的 autopilot 域注入)或 cwd 上溯 .serenity。
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
import { existsSync, readFileSync, statSync, readdirSync, writeFileSync, mkdirSync } from 'node:fs'
|
|
25
|
-
import { join, resolve, basename, dirname } from 'node:path'
|
|
26
|
-
import { spawnSync } from 'node:child_process'
|
|
27
|
-
|
|
28
|
-
const DEFAULT_BIAS_PROVIDER = 'autopilot-bias.ts'
|
|
29
|
-
const AUTO_SUFFIX = '--auto'
|
|
30
|
-
const MOTIVATION_MARKER = '下一轮动机'
|
|
31
|
-
const CONFIG_PATHS = ['.opencode/serenity.json', '.dsh/serenity.json']
|
|
32
|
-
|
|
33
|
-
/** 偏见内容提供者脚本脚手架模板(init 生成;CCC 按自己的反馈信息来源改写) */
|
|
34
|
-
const BIAS_TEMPLATE = `#!/usr/bin/env bun
|
|
35
|
-
/**
|
|
36
|
-
* autopilot-bias.ts — 自主轨迹偏见内容提供者(CCC 实现)
|
|
37
|
-
*
|
|
38
|
-
* stdout 输出一行/一段文本 = 本轮唤起注入的偏见内容(反事实问题 / 探索方向 /
|
|
39
|
-
* 任何让轨迹偏离既有路径的输入)。偏见内容归 CCC——用本 CCC 自己的反馈信息来源
|
|
40
|
-
* 保证"足够随机"(历史会话 / 技能 / 文档 / 外部信息 / 真随机源……)。
|
|
41
|
-
*
|
|
42
|
-
* 本文件为脚手架——请按本 CCC 的信息来源改写。
|
|
43
|
-
*/
|
|
44
|
-
const sources = [
|
|
45
|
-
'AGENT_SESSIONS 中的历史会话',
|
|
46
|
-
'.opencode/skills 技能目录',
|
|
47
|
-
'docs/ 设计文档',
|
|
48
|
-
'…(CCC 自己的信息来源)',
|
|
49
|
-
]
|
|
50
|
-
const pick = sources[Math.floor(Math.random() * sources.length)]
|
|
51
|
-
console.log(\`反事实:如果「\${pick}」换个做法会怎样?\`)
|
|
52
|
-
`
|
|
53
|
-
|
|
54
|
-
/** 背景摘要(一站式的第一节——CCC agent 快速理解"为什么/验证什么") */
|
|
55
|
-
const BACKGROUND = [
|
|
56
|
-
'═══ 自主轨迹实验(Self-Sustaining Trajectory)═══',
|
|
57
|
-
'背景:Trajectory 是主体(Agent 可替换、Session 载体可重建)。瓶颈 = 人类 waiting——',
|
|
58
|
-
' 轨迹以"等待人类"为推进条件时,事件序列时间被人类响应间隔锚定,运转被拖慢。',
|
|
59
|
-
'猜想:无人等待的 trajectory——时钟自动唤起 + 先验偏见(自生动机 + 偏见内容)→ 运转加速。',
|
|
60
|
-
'验证:P4 可自动唤起并携带偏见 / P5 速度提升→更快产生满意效果;反证=熵增失控/自我确认/噪音化。',
|
|
61
|
-
'理论:specs §0.7 记录器→校准器(预测加工)。完整定义:doc(SKILL.md)。',
|
|
62
|
-
'',
|
|
63
|
-
].join('\n')
|
|
64
|
-
|
|
65
|
-
interface AutoConfig {
|
|
66
|
-
enabled?: boolean
|
|
67
|
-
intervalHours?: number
|
|
68
|
-
biasProvider?: string
|
|
69
|
-
/** 顶层提示词(v1.26.17):CCC 定义的稳定提示词,每次唤起最先注入(顶层约束/质量要求) */
|
|
70
|
-
topPrompt?: string
|
|
71
|
-
session?: string
|
|
72
|
-
avoidWakeHours?: { start?: number; end?: number }
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// ── 基础设施 ──
|
|
76
|
-
|
|
77
|
-
function findRoot(): string | null {
|
|
78
|
-
const fromEnv = process.env.SERENITY_ROOT
|
|
79
|
-
if (fromEnv && existsSync(join(fromEnv, '.serenity'))) return fromEnv
|
|
80
|
-
let cur = resolve(process.cwd())
|
|
81
|
-
while (true) {
|
|
82
|
-
if (existsSync(join(cur, '.serenity'))) return cur
|
|
83
|
-
const parent = dirname(cur)
|
|
84
|
-
if (parent === cur) return null
|
|
85
|
-
cur = parent
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function readUtf8(p: string): string {
|
|
90
|
-
return readFileSync(p, 'utf-8').replace(/^\uFEFF/, '')
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* 读 autopilot 配置:与插件侧 `readAutopilotSettings` **同一回退链**
|
|
95
|
-
* (`trajectory.autopilot` → `autopilotTrajectory` → `autotrajectory`,D58;逐级回退、不回写)。
|
|
96
|
-
*
|
|
97
|
-
* 为什么必须对齐(v1.33 修正):脚本与插件是两个读侧。若只认旧键,CCC 把配置迁到新键后,
|
|
98
|
-
* 调度器照跑而 `container_admin autopilot status` 报"未配置"——**静默的假阴性**。
|
|
99
|
-
*/
|
|
100
|
-
function loadConfig(root: string): AutoConfig | null {
|
|
101
|
-
for (const rel of CONFIG_PATHS) {
|
|
102
|
-
const p = join(root, rel)
|
|
103
|
-
if (!existsSync(p)) continue
|
|
104
|
-
try {
|
|
105
|
-
const cfg = JSON.parse(readUtf8(p)) as {
|
|
106
|
-
autopilotTrajectory?: AutoConfig
|
|
107
|
-
autotrajectory?: AutoConfig
|
|
108
|
-
trajectory?: { autopilot?: AutoConfig }
|
|
109
|
-
}
|
|
110
|
-
return cfg.trajectory?.autopilot ?? cfg.autopilotTrajectory ?? cfg.autotrajectory ?? null
|
|
111
|
-
} catch {
|
|
112
|
-
return null
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
return null
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/** 偏见提供者脚本绝对路径(根内强制——逃逸拒绝) */
|
|
119
|
-
function biasProviderPath(root: string, providerRel: string): string {
|
|
120
|
-
const rootAbs = resolve(root)
|
|
121
|
-
const abs = resolve(root, providerRel)
|
|
122
|
-
if (abs !== rootAbs && !abs.startsWith(rootAbs + '/')) {
|
|
123
|
-
throw new Error(`biasProvider 路径逃逸(须在 CCC 根内): ${providerRel}`)
|
|
124
|
-
}
|
|
125
|
-
return abs
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/** 运行偏见提供者脚本(bun 优先,node 兜底),返回偏见内容或错误信息 */
|
|
129
|
-
function runBiasProvider(root: string, providerRel: string): { text: string | null; error: string | null } {
|
|
130
|
-
let scriptAbs: string
|
|
131
|
-
try {
|
|
132
|
-
scriptAbs = biasProviderPath(root, providerRel)
|
|
133
|
-
} catch (e) {
|
|
134
|
-
return { text: null, error: String((e as Error).message) }
|
|
135
|
-
}
|
|
136
|
-
if (!existsSync(scriptAbs)) {
|
|
137
|
-
return { text: null, error: `请在 CCC 根目录实现偏见内容提供者脚本: ${providerRel}(container_admin autopilot init 可生成模板)` }
|
|
138
|
-
}
|
|
139
|
-
for (const cmd of ['bun', process.execPath]) {
|
|
140
|
-
try {
|
|
141
|
-
const r = spawnSync(cmd, [scriptAbs], { encoding: 'utf-8', timeout: 600_000, stdio: ['ignore', 'pipe', 'pipe'] })
|
|
142
|
-
if (r.status === 0) {
|
|
143
|
-
const text = (r.stdout ?? '').trim()
|
|
144
|
-
return { text: text || null, error: null }
|
|
145
|
-
}
|
|
146
|
-
if ((r.error as NodeJS.ErrnoException | undefined)?.code === 'ENOENT') continue
|
|
147
|
-
return { text: null, error: `偏见内容提供者脚本执行失败(exit ${r.status ?? '?'}): ${r.stderr?.trim() || r.stdout?.trim() || ''}` }
|
|
148
|
-
} catch {
|
|
149
|
-
continue
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
return { text: null, error: '偏见内容提供者脚本无法运行(bun 与 node 均不可用)' }
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/** 目标 SESSION.md:**session 必填**(S###/目录名匹配)——自动唤起不默认任何会话(CCC 日常多轨迹并行);未配置/未命中 → null */
|
|
156
|
-
function resolveTargetMd(root: string, cfg: AutoConfig): string | null {
|
|
157
|
-
if (!cfg?.session) return null
|
|
158
|
-
const sessionsDir = join(root, 'AGENT_SESSIONS')
|
|
159
|
-
if (!existsSync(sessionsDir)) return null
|
|
160
|
-
const dirs = readdirSync(sessionsDir, { withFileTypes: true })
|
|
161
|
-
.filter((d) => d.isDirectory())
|
|
162
|
-
.map((d) => join(sessionsDir, d.name))
|
|
163
|
-
for (const d of dirs) {
|
|
164
|
-
const md = join(d, 'SESSION.md')
|
|
165
|
-
if (existsSync(md) && basename(d).includes(cfg.session)) return md
|
|
166
|
-
}
|
|
167
|
-
return null
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
function beijingHour(nowMs: number): number {
|
|
171
|
-
return Math.floor(((nowMs + 8 * 3600_000) % 86400_000) / 3600_000)
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
function inAllowedWindow(nowMs: number, avoid?: { start?: number; end?: number }): boolean {
|
|
175
|
-
const start = avoid?.start ?? 8
|
|
176
|
-
const end = avoid?.end ?? 18
|
|
177
|
-
const h = beijingHour(nowMs)
|
|
178
|
-
if (start <= end) return h < start || h >= end
|
|
179
|
-
return h >= end && h < start
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// ── 子命令实现 ──
|
|
183
|
-
|
|
184
|
-
function doc(root: string): string {
|
|
185
|
-
const p = join(dirname(process.argv[1] ?? ''), '..', 'SKILL.md')
|
|
186
|
-
if (existsSync(p)) return readUtf8(p)
|
|
187
|
-
return `SKILL.md 未找到(${p})——实验定义见 serenity-acc-specs docs/self-sustaining-trajectory-hypothesis.md §7.1`
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
function check(root: string): string {
|
|
191
|
-
const cfg = loadConfig(root)
|
|
192
|
-
const lines: string[] = [`[autopilot-trajectory] 实验就绪度检查(CCC: ${basename(root)})`, '']
|
|
193
|
-
const fail: string[] = []
|
|
194
|
-
|
|
195
|
-
if (!cfg) {
|
|
196
|
-
lines.push('✗ 未配置 trajectory.autopilot(.opencode/serenity.json 缺段)——container_admin autopilot init 一键初始化')
|
|
197
|
-
fail.push('config')
|
|
198
|
-
} else if (!cfg.enabled) {
|
|
199
|
-
lines.push('✗ trajectory.autopilot.enabled = false(未开启)')
|
|
200
|
-
fail.push('enabled')
|
|
201
|
-
} else {
|
|
202
|
-
lines.push(`✓ enabled = true`)
|
|
203
|
-
lines.push(` intervalHours = ${cfg.intervalHours ?? 12}`)
|
|
204
|
-
lines.push(` biasProvider = ${cfg.biasProvider?.trim() || DEFAULT_BIAS_PROVIDER}`)
|
|
205
|
-
if (cfg.topPrompt?.trim()) {
|
|
206
|
-
lines.push(`✓ topPrompt(轨迹焦点)已定义: ${cfg.topPrompt.trim().slice(0, 60)}${cfg.topPrompt.trim().length > 60 ? '…' : ''}(每次唤起最先注入,锚定防漂移)`)
|
|
207
|
-
} else {
|
|
208
|
-
lines.push(`⚠ topPrompt(轨迹焦点)未定义——建议 CCC 定义 trajectory.autopilot 时填写本轨迹核心焦点(实验观察:无焦点锚定,多轮唤起轨迹易漂移腐化)`)
|
|
209
|
-
}
|
|
210
|
-
if (cfg.session) lines.push(` session = ${cfg.session}`)
|
|
211
|
-
const avoid = cfg.avoidWakeHours
|
|
212
|
-
lines.push(` 唤起窗口避开北京 ${avoid?.start ?? 8}~${avoid?.end ?? 18} 点(用量峰谷省钱)`)
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
const provider = cfg?.biasProvider?.trim() || DEFAULT_BIAS_PROVIDER
|
|
216
|
-
if (cfg?.enabled) {
|
|
217
|
-
const bias = runBiasProvider(root, provider)
|
|
218
|
-
if (bias.error) {
|
|
219
|
-
lines.push(`✗ 偏见内容提供者未就绪: ${bias.error}`)
|
|
220
|
-
fail.push('biasProvider')
|
|
221
|
-
} else {
|
|
222
|
-
lines.push(`✓ 偏见内容提供者可运行(输出示例: ${bias.text ?? '(空输出)'})`)
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
const md = resolveTargetMd(root, cfg ?? {})
|
|
227
|
-
if (!cfg?.session) {
|
|
228
|
-
lines.push('✗ 未配置 session(必填——自动唤起不默认任何会话,CCC 日常多轨迹并行)')
|
|
229
|
-
fail.push('session')
|
|
230
|
-
} else if (md) {
|
|
231
|
-
const flag = basename(dirname(md)).endsWith(AUTO_SUFFIX)
|
|
232
|
-
lines.push(`${flag ? '✓' : '✗'} 目标会话目录${flag ? '带' : '未带'} --auto 标志:${basename(dirname(md))}`)
|
|
233
|
-
if (!flag) {
|
|
234
|
-
lines.push(` → 目录名需以 --auto 结尾(AGENT_SESSIONS/<date>--<desc>--auto/)`)
|
|
235
|
-
fail.push('autoFlag')
|
|
236
|
-
}
|
|
237
|
-
const content = readUtf8(md)
|
|
238
|
-
if (content.includes(MOTIVATION_MARKER)) {
|
|
239
|
-
lines.push(`✓ SESSION.md 含「下一轮动机」段(自生偏见)`)
|
|
240
|
-
} else {
|
|
241
|
-
lines.push(`· SESSION.md 无「下一轮动机」段(可选——纯偏见内容亦可)`)
|
|
242
|
-
}
|
|
243
|
-
} else {
|
|
244
|
-
lines.push(`✗ 目标会话未命中:${cfg.session}(AGENT_SESSIONS 无匹配目录)`)
|
|
245
|
-
fail.push('session')
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
lines.push('')
|
|
249
|
-
lines.push(fail.length === 0 ? '✅ 实验就绪——等待时钟唤起(前台可见)' : `⚠️ 未就绪:${fail.join(', ')}`)
|
|
250
|
-
return lines.join('\n')
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
function status(root: string): string {
|
|
254
|
-
const cfg = loadConfig(root)
|
|
255
|
-
const now = Date.now()
|
|
256
|
-
const lines: string[] = [`[autopilot-trajectory] 实验状态(CCC: ${basename(root)},北京 ${beijingHour(now)} 点)`, '']
|
|
257
|
-
if (!cfg?.enabled) {
|
|
258
|
-
lines.push('trajectory.autopilot 未启用(enabled=false 或未配置)——零资源占用')
|
|
259
|
-
return lines.join('\n')
|
|
260
|
-
}
|
|
261
|
-
lines.push(`配置: intervalHours=${cfg.intervalHours ?? 12} | biasProvider=${cfg.biasProvider?.trim() || DEFAULT_BIAS_PROVIDER}${cfg.session ? ` | session=${cfg.session}` : ''}${cfg.topPrompt?.trim() ? ' | topPrompt ✓' : ''}`)
|
|
262
|
-
const md = resolveTargetMd(root, cfg)
|
|
263
|
-
if (!md) {
|
|
264
|
-
lines.push('目标会话:未找到')
|
|
265
|
-
return lines.join('\n')
|
|
266
|
-
}
|
|
267
|
-
const mtime = statSync(md).mtimeMs
|
|
268
|
-
const idleHours = (now - mtime) / 3600_000
|
|
269
|
-
const interval = Math.max(1, cfg.intervalHours ?? 12)
|
|
270
|
-
lines.push(`目标会话:${basename(dirname(md))}${basename(dirname(md)).endsWith(AUTO_SUFFIX) ? '(--auto ✓)' : '(无 --auto 标志)'}`)
|
|
271
|
-
lines.push(`上次轨迹活动:${idleHours.toFixed(1)} 小时前(阈值 ${interval}h)`)
|
|
272
|
-
lines.push(`唤起窗口:${inAllowedWindow(now, cfg.avoidWakeHours) ? '✅ 允许唤起' : '⏸ 高峰避开中(北京 8~18)'}`)
|
|
273
|
-
const wakeable = inAllowedWindow(now, cfg.avoidWakeHours) && idleHours >= interval
|
|
274
|
-
lines.push(`是否可唤起:${wakeable ? '✅ 是(等待下一个 10min tick)' : idleHours < interval ? `否——距上次活动不足 ${interval}h` : '否——高峰避开中'}`)
|
|
275
|
-
return lines.join('\n')
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
function guide(): string {
|
|
279
|
-
return [
|
|
280
|
-
'[autopilot-trajectory] 实验步骤指引',
|
|
281
|
-
'',
|
|
282
|
-
'① 初始化(一键):container_admin autopilot init',
|
|
283
|
-
' ——写配置(.opencode/serenity.json 的 trajectory.autopilot 段)+ 生成偏见提供者脚本模板(CCC 根 autopilot-bias.ts)',
|
|
284
|
-
'② **定义轨迹焦点(topPrompt)**:编辑配置中的 topPrompt——**CCC 自己填写**本轨迹的核心',
|
|
285
|
-
' 目标/纪律/质量要求(示例:"持续深化某领域认知,产出可重建的结论与决策记录")。',
|
|
286
|
-
' 它会在每次唤起时最先注入([轨迹焦点] 段),作为稳定焦点锚定 trajectory 防漂移——',
|
|
287
|
-
' **实验观察:无焦点锚定时多轮唤起轨迹腐化严重(焦点丢失)**。勿留空。',
|
|
288
|
-
'③ 实现偏见内容提供者:编辑 autopilot-bias.ts,stdout 输出偏见内容(反事实方向/探索动机,',
|
|
289
|
-
' 用本 CCC 自己的信息来源保证"足够随机");container_admin autopilot generate-bias 验证',
|
|
290
|
-
'④ 标记目标会话:目录名加 --auto 后缀 AGENT_SESSIONS/<date>--<desc>--auto/',
|
|
291
|
-
' (可选)该 SESSION.md 写「下一轮动机」段作自生偏见',
|
|
292
|
-
'⑤ 验证就绪:container_admin autopilot status(一站式报告应为 ✅;topPrompt 未定义会 ⚠ 提示)',
|
|
293
|
-
'⑥ 观察:无人类活动满 intervalHours 且北京非高峰 → 前台会话自动出现 [自主轨迹唤起]',
|
|
294
|
-
' 产出落 SESSION.md「自主探索日志」+ 预写「下一轮动机」',
|
|
295
|
-
'',
|
|
296
|
-
'分工:焦点(topPrompt)= 稳定锚,每轮不变;偏见(biasProvider)= 随机探索方向,每轮不同——两者都由 CCC 定义。',
|
|
297
|
-
'定义全文见 experiments/autopilot-trajectory/SKILL.md(开发面:bun <本脚本> doc)',
|
|
298
|
-
'运行态诊断(live 会话 / agent 定位 / 唤醒注册表 / 本条件链):专属工具 acc-diag(ACC 负责人)',
|
|
299
|
-
].join('\n')
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
/** 初始化:合并写配置(不覆盖其他段)+ 生成偏见提供者脚本模板(已存在则跳过) */
|
|
303
|
-
function init(root: string): string {
|
|
304
|
-
const out: string[] = ['[autopilot-trajectory] 初始化实验', '']
|
|
305
|
-
|
|
306
|
-
// ① 写配置
|
|
307
|
-
let cfgPath = join(root, CONFIG_PATHS[0]!)
|
|
308
|
-
if (!existsSync(cfgPath)) {
|
|
309
|
-
const alt = join(root, CONFIG_PATHS[1]!)
|
|
310
|
-
cfgPath = existsSync(alt) ? alt : cfgPath
|
|
311
|
-
}
|
|
312
|
-
mkdirSync(dirname(cfgPath), { recursive: true })
|
|
313
|
-
let merged: Record<string, unknown> = {}
|
|
314
|
-
if (existsSync(cfgPath)) {
|
|
315
|
-
try {
|
|
316
|
-
merged = JSON.parse(readUtf8(cfgPath)) as Record<string, unknown>
|
|
317
|
-
} catch {
|
|
318
|
-
/* 损坏则重建 */
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
// 写入 **新键** `trajectory.autopilot`(D58);旧键 `autopilotTrajectory`/`autotrajectory`
|
|
322
|
-
// 若存在则**迁移并删除**——保留两处会形成"改了不生效"的双真相源(读侧新键优先)。
|
|
323
|
-
const traj = (merged.trajectory as Record<string, unknown> | undefined) ?? {}
|
|
324
|
-
const legacy =
|
|
325
|
-
(merged.autopilotTrajectory as Record<string, unknown> | undefined) ??
|
|
326
|
-
(merged.autotrajectory as Record<string, unknown> | undefined)
|
|
327
|
-
const at = (traj.autopilot as Record<string, unknown> | undefined) ?? legacy ?? {}
|
|
328
|
-
merged.trajectory = {
|
|
329
|
-
...traj,
|
|
330
|
-
autopilot: {
|
|
331
|
-
enabled: true,
|
|
332
|
-
intervalHours: 12,
|
|
333
|
-
biasProvider: DEFAULT_BIAS_PROVIDER,
|
|
334
|
-
// 轨迹焦点(topPrompt):**CCC 自己定义**本轨迹的核心目标/纪律/质量要求——每次唤起最先
|
|
335
|
-
// 注入,作为稳定焦点锚定 trajectory,防止多轮自主唤起中焦点丢失(腐化)。请按本 CCC
|
|
336
|
-
// 的轨迹目标改写,不要留空(留空 = 唤起无焦点锚定,轨迹易漂移)。
|
|
337
|
-
topPrompt: '本轨迹的核心焦点:<CCC 填写——例如:持续深化某领域认知,产出可重建的结论与决策记录>',
|
|
338
|
-
...at,
|
|
339
|
-
},
|
|
340
|
-
}
|
|
341
|
-
const migrated = Boolean(legacy)
|
|
342
|
-
delete merged.autopilotTrajectory
|
|
343
|
-
delete merged.autotrajectory
|
|
344
|
-
writeFileSync(cfgPath, `${JSON.stringify(merged, null, 2)}\n`)
|
|
345
|
-
out.push(`✓ 配置写入: ${cfgPath}`)
|
|
346
|
-
out.push(` trajectory.autopilot = ${JSON.stringify((merged.trajectory as Record<string, unknown>).autopilot)}`)
|
|
347
|
-
if (migrated) out.push(' ↑ 已从旧键 autopilotTrajectory/autotrajectory 迁移到 trajectory.autopilot(旧键已删除,避免双真相源)')
|
|
348
|
-
out.push(` ⚠ 请编辑 topPrompt 为**本 CCC 的轨迹焦点**(现为占位——每次唤起最先注入,防轨迹漂移,勿留空)`)
|
|
349
|
-
|
|
350
|
-
// ② 生成偏见提供者脚本模板
|
|
351
|
-
const scriptAbs = biasProviderPath(root, DEFAULT_BIAS_PROVIDER)
|
|
352
|
-
if (existsSync(scriptAbs)) {
|
|
353
|
-
out.push(`· 偏见提供者脚本已存在(保留): ${DEFAULT_BIAS_PROVIDER}`)
|
|
354
|
-
} else {
|
|
355
|
-
writeFileSync(scriptAbs, BIAS_TEMPLATE)
|
|
356
|
-
out.push(`✓ 已生成偏见提供者脚本模板: ${DEFAULT_BIAS_PROVIDER}(编辑它,stdout 输出偏见内容)`)
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
out.push('', '下一步:② 编辑配置 topPrompt(轨迹焦点——CCC 自己填写本轨迹核心目标,勿留空)→ ③ 标记目标会话 --auto 后缀 → ⑤ container_admin autopilot status 验证就绪')
|
|
360
|
-
return out.join('\n')
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
/** random:运行偏见提供者脚本,输出当前偏见内容(验证) */
|
|
364
|
-
function random(root: string): string {
|
|
365
|
-
const cfg = loadConfig(root)
|
|
366
|
-
const provider = cfg?.biasProvider?.trim() || DEFAULT_BIAS_PROVIDER
|
|
367
|
-
const bias = runBiasProvider(root, provider)
|
|
368
|
-
if (bias.error) return `[autopilot-trajectory] ✗ ${bias.error}`
|
|
369
|
-
return `[autopilot-trajectory] 当前偏见内容(${provider}):\n${bias.text ?? '(空输出)'}`
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
/** 一站式全报告:背景 + 就绪检查 + 状态 + 下一步 + 指引(CCC agent 看一次即懂并知道下一步) */
|
|
373
|
-
function all(root: string): string {
|
|
374
|
-
const cfg = loadConfig(root)
|
|
375
|
-
const ready = check(root)
|
|
376
|
-
const stat = status(root)
|
|
377
|
-
const next: string[] = ['═══ 下一步 ═══']
|
|
378
|
-
if (!cfg) {
|
|
379
|
-
next.push('→ 本 CCC 尚未配置 trajectory.autopilot。开始实验:container_admin autopilot init 一键初始化。')
|
|
380
|
-
} else if (!cfg.enabled) {
|
|
381
|
-
next.push('→ trajectory.autopilot.enabled 为 false——置 true 开启实验(或 init 重新初始化)。')
|
|
382
|
-
} else if (ready.includes('✗')) {
|
|
383
|
-
next.push('→ 存在未就绪项(见上)。补齐后重跑本命令确认 ✅。')
|
|
384
|
-
} else {
|
|
385
|
-
next.push('→ 已就绪 ✅。保持会话空闲满 intervalHours 且北京非高峰 → 自动唤起(前台可见)。')
|
|
386
|
-
next.push('→ 之后可随时 container_admin autopilot status 查看距下次唤起的进度。')
|
|
387
|
-
}
|
|
388
|
-
return [BACKGROUND, ready, '', stat, '', next.join('\n'), '', guide()].join('\n')
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
/** 唤起条件链诊断(单 CCC)——逐条件当前值 + 阻断点 + 修复建议 */
|
|
392
|
-
function diagCcc(root: string): string {
|
|
393
|
-
const now = Date.now()
|
|
394
|
-
const lines: string[] = [`═══ 自主轨迹唤起诊断:${basename(root)}(${root})═══`]
|
|
395
|
-
const cfg = loadConfig(root)
|
|
396
|
-
const blocks: string[] = []
|
|
397
|
-
const suggest: string[] = []
|
|
398
|
-
|
|
399
|
-
// ① enabled(定时器是否启动)
|
|
400
|
-
if (!cfg) {
|
|
401
|
-
blocks.push('✗ trajectory.autopilot 未配置(定时器不启动)')
|
|
402
|
-
suggest.push('配置:.opencode/serenity.json 加 trajectory.autopilot 段(container_admin autopilot init 可生成)')
|
|
403
|
-
} else if (!cfg.enabled) {
|
|
404
|
-
blocks.push('✗ enabled = false(定时器不启动)')
|
|
405
|
-
suggest.push('置 enabled: true')
|
|
406
|
-
} else {
|
|
407
|
-
blocks.push('✓ enabled = true')
|
|
408
|
-
}
|
|
409
|
-
if (cfg) {
|
|
410
|
-
blocks.push(` 配置: intervalHours=${cfg.intervalHours ?? 12} | biasProvider=${cfg.biasProvider?.trim() || DEFAULT_BIAS_PROVIDER}${cfg.session ? ` | session=${cfg.session}` : ' | session=未配置'}`)
|
|
411
|
-
const avoid = cfg.avoidWakeHours
|
|
412
|
-
blocks.push(` 窗口避开北京 ${avoid?.start ?? 8}~${avoid?.end ?? 18} 点`)
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
// ② session(必填——不默认任何会话)
|
|
416
|
-
const md = resolveTargetMd(root, cfg ?? {})
|
|
417
|
-
if (!cfg?.session) {
|
|
418
|
-
blocks.push('✗ session 未配置(必填——自动唤起不默认任何会话)')
|
|
419
|
-
suggest.push('配置 session: "S###"(目标会话 S###/目录名)')
|
|
420
|
-
} else if (!md) {
|
|
421
|
-
blocks.push(`✗ session=${cfg.session} 未命中(AGENT_SESSIONS 无匹配目录)`)
|
|
422
|
-
suggest.push('确认目标会话存在(目录名含该关键字)')
|
|
423
|
-
} else {
|
|
424
|
-
blocks.push(`✓ session=${cfg.session} 命中(${basename(dirname(md))})`)
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
// ③ --auto 会话标志
|
|
428
|
-
if (md) {
|
|
429
|
-
const flag = basename(dirname(md)).endsWith(AUTO_SUFFIX)
|
|
430
|
-
if (flag) {
|
|
431
|
-
blocks.push('✓ 会话目录带 --auto 标志')
|
|
432
|
-
} else {
|
|
433
|
-
blocks.push(`✗ 会话目录无 --auto 标志(${basename(dirname(md))})`)
|
|
434
|
-
suggest.push('目录名加 --auto 后缀:AGENT_SESSIONS/<date>--<desc>--auto/')
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
// ④ mtime 间隔(无人类活动时长)
|
|
439
|
-
if (md) {
|
|
440
|
-
const mtime = statSync(md).mtimeMs
|
|
441
|
-
const idle = (now - mtime) / 3600_000
|
|
442
|
-
const interval = Math.max(1, cfg?.intervalHours ?? 12)
|
|
443
|
-
if (idle >= interval) blocks.push(`✓ 距上次轨迹活动 ${idle.toFixed(1)}h ≥ 阈值 ${interval}h`)
|
|
444
|
-
else blocks.push(`⏸ 距上次轨迹活动 ${idle.toFixed(1)}h < 阈值 ${interval}h(等待中——不满足不唤起)`)
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
// ⑤ 北京时间唤起窗口
|
|
448
|
-
const h = beijingHour(now)
|
|
449
|
-
const inWin = inAllowedWindow(now, cfg?.avoidWakeHours)
|
|
450
|
-
blocks.push(`${inWin ? '✓' : '⏸'} 当前北京 ${h} 点——${inWin ? '在唤起窗口内' : '高峰避开中(缺省 8~18,用量峰谷省钱)'}`)
|
|
451
|
-
|
|
452
|
-
// ⑥ 偏见内容提供者脚本
|
|
453
|
-
if (cfg?.enabled) {
|
|
454
|
-
const provider = cfg.biasProvider?.trim() || DEFAULT_BIAS_PROVIDER
|
|
455
|
-
const bias = runBiasProvider(root, provider)
|
|
456
|
-
if (bias.error) {
|
|
457
|
-
blocks.push(`✗ 偏见脚本: ${bias.error}`)
|
|
458
|
-
suggest.push('实现偏见脚本(container_admin autopilot init 生成模板后编辑)')
|
|
459
|
-
} else {
|
|
460
|
-
blocks.push(`✓ 偏见脚本可运行(输出: ${bias.text ?? '(空)'})`)
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
lines.push(...blocks.map((b) => ` ${b}`))
|
|
465
|
-
lines.push('')
|
|
466
|
-
const bad = blocks.filter((b) => b.startsWith('✗'))
|
|
467
|
-
if (bad.length === 0) {
|
|
468
|
-
lines.push('✅ 唤起条件全部满足——等待下一个 10min tick 自动唤起(前台可见)')
|
|
469
|
-
} else {
|
|
470
|
-
lines.push(`⚠️ 阻断点 ${bad.length} 项(全部满足才唤起):`)
|
|
471
|
-
for (const s of suggest) lines.push(` → ${s}`)
|
|
472
|
-
}
|
|
473
|
-
return lines.join('\n')
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
/** diag:--ccc <path> 指定目标 CCC;无参扫描常见 CCC 根(配置了 trajectory.autopilot 的优先) */
|
|
477
|
-
function diag(): string {
|
|
478
|
-
const argIdx = process.argv.indexOf('--ccc')
|
|
479
|
-
if (argIdx >= 0 && process.argv[argIdx + 1]) {
|
|
480
|
-
return diagCcc(resolve(process.argv[argIdx + 1]!))
|
|
481
|
-
}
|
|
482
|
-
const roots = new Set<string>()
|
|
483
|
-
const envRoot = process.env.SERENITY_ROOT
|
|
484
|
-
if (envRoot && existsSync(join(envRoot, '.serenity'))) roots.add(envRoot)
|
|
485
|
-
// 递归扫描 /home/yh 两层(覆盖 /home/yh/home/*、/home/yh/our-home/* 及任意实验 CCC 位置)
|
|
486
|
-
for (const base of ['/home/yh']) {
|
|
487
|
-
collectCccs(base, 0, roots, 2)
|
|
488
|
-
}
|
|
489
|
-
const list = [...roots]
|
|
490
|
-
if (list.length === 0) return '[autopilot-trajectory diag] 未发现 CCC(用 --ccc <path> 指定目标)'
|
|
491
|
-
const ordered = [...list.filter((r) => loadConfig(r)?.enabled), ...list.filter((r) => !loadConfig(r)?.enabled)]
|
|
492
|
-
return ordered.map(diagCcc).join('\n\n')
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
/** 递归收集 .serenity 标记目录(跳过隐藏目录;maxDepth 层内) */
|
|
496
|
-
function collectCccs(dir: string, depth: number, out: Set<string>, maxDepth: number): void {
|
|
497
|
-
if (depth > maxDepth || !existsSync(dir)) return
|
|
498
|
-
for (const d of readdirSync(dir, { withFileTypes: true })) {
|
|
499
|
-
if (!d.isDirectory() || d.name.startsWith('.')) continue
|
|
500
|
-
const r = join(dir, d.name)
|
|
501
|
-
if (existsSync(join(r, '.serenity'))) out.add(r)
|
|
502
|
-
collectCccs(r, depth + 1, out, maxDepth)
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
function main(): void {
|
|
507
|
-
const cmd = process.argv[2] ?? 'all'
|
|
508
|
-
const root = findRoot()
|
|
509
|
-
if (!root) {
|
|
510
|
-
console.error('[autopilot-trajectory] ✗ 未找到 CCC 根(无 .serenity;container_admin 的 autopilot 域会自动注入 SERENITY_ROOT)')
|
|
511
|
-
process.exit(1)
|
|
512
|
-
}
|
|
513
|
-
switch (cmd) {
|
|
514
|
-
case 'all':
|
|
515
|
-
console.log(all(root))
|
|
516
|
-
break
|
|
517
|
-
case 'init':
|
|
518
|
-
console.log(init(root))
|
|
519
|
-
break
|
|
520
|
-
case 'random':
|
|
521
|
-
console.log(random(root))
|
|
522
|
-
break
|
|
523
|
-
case 'diag':
|
|
524
|
-
console.log(diag())
|
|
525
|
-
break
|
|
526
|
-
case 'doc':
|
|
527
|
-
console.log(doc(root))
|
|
528
|
-
break
|
|
529
|
-
case 'check':
|
|
530
|
-
console.log(check(root))
|
|
531
|
-
break
|
|
532
|
-
case 'status':
|
|
533
|
-
console.log(status(root))
|
|
534
|
-
break
|
|
535
|
-
case 'guide':
|
|
536
|
-
console.log(guide())
|
|
537
|
-
break
|
|
538
|
-
default:
|
|
539
|
-
console.error(`[autopilot-trajectory] 未知子命令: ${cmd}(可用: 无参一站式 / init / random / diag / doc / check / status / guide)`)
|
|
540
|
-
process.exit(2)
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
if (import.meta.main) {
|
|
545
|
-
main()
|
|
546
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* autopilot-script.ts — 包内 autopilot 脚本通道(v1.33 提取;S142 §32「logbook × trajectory 合并」)
|
|
3
|
-
*
|
|
4
|
-
* 为什么单独成模块(R↓):autopilot 的三个动作(`autopilot-status` / `autopilot-init` /
|
|
5
|
-
* `generate-autopilot-bias`,原 `all` / `init` / `random`)**归 `container_admin`**,而
|
|
6
|
-
* 脚本定位与执行逻辑此前长在 `tools/autopilot-trajectory.ts` 里。若不提取,要么在两处
|
|
7
|
-
* 重复 spawn 逻辑(熵),要么让 container_admin 依赖一个即将删除的工具文件(错向依赖)。
|
|
8
|
-
* ⇒ 提取为**单真相源**:脚本定位(`findExpScript` / `EXP_SCRIPT`)+ 执行(`runAutopilotScript`)。
|
|
9
|
-
*
|
|
10
|
-
* 脚本本体:`experiments/autopilot-trajectory/scripts/autopilot-trajectory.ts`(随 npm files 分发)。
|
|
11
|
-
* 契约:argv[2] = 子命令(`all` | `init` | `random` | `diag` | `doc` | `check` | `status` | `guide`),
|
|
12
|
-
* 环境变量 `SERENITY_ROOT` = CCC 根;stdout 即人读结果。
|
|
13
|
-
* ⚠️ 脚本侧的 `diag`/`doc`/`check`/`status`/`guide` 已**不在 CCC 工具面**(S142 §32.9:
|
|
14
|
-
* `diag` 归 ACC 负责人、其余并入 `autopilot-status`)——脚本保留这些子命令以便开发面直接调用。
|
|
15
|
-
*/
|
|
16
|
-
/**
|
|
17
|
-
* 定位包内脚本(npm files 分发 experiments/autopilot-trajectory/)。
|
|
18
|
-
* 布局差异:tsdown bundle 后 import.meta.url 指向 lib/index.js(lib → 包根 1 层);
|
|
19
|
-
* vitest 源码直跑时指向 src/tools/x.ts(src/tools → 包根 2 层)——逐级上溯查找,
|
|
20
|
-
* 两种布局都稳(找到 experiments/autopilot-trajectory/scripts/autopilot-trajectory.ts 即止)。
|
|
21
|
-
* @param startDir 起始目录(通常为模块自身所在目录)
|
|
22
|
-
* @returns 脚本绝对路径;未找到 null
|
|
23
|
-
*/
|
|
24
|
-
export declare function findExpScript(startDir: string): string | null;
|
|
25
|
-
/** 包内脚本(上溯查找;找不到 → 调用方报错提示包完整性) */
|
|
26
|
-
export declare const EXP_SCRIPT: string | null;
|
|
27
|
-
/** 脚本执行结果(人读;`error` 非空即失败,调用方不得静默) */
|
|
28
|
-
export interface AutopilotScriptResult {
|
|
29
|
-
/** 成功时的 stdout(已 trim) */
|
|
30
|
-
output?: string;
|
|
31
|
-
/** 失败原因(人读,含"包不完整/缺 bun/脚本退出码"三类) */
|
|
32
|
-
error?: string;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* 执行包内 autopilot 脚本(bun 优先;同步、10min 超时、注入 CCC 根)。
|
|
36
|
-
* @param root CCC 根(注入 `SERENITY_ROOT`;null 则靠脚本自行上溯 .serenity)
|
|
37
|
-
* @param action 脚本子命令(`all` | `init` | `random` | …)
|
|
38
|
-
* @returns `{ output }` 或 `{ error }`(不抛错——调用方决定如何呈现)
|
|
39
|
-
*/
|
|
40
|
-
export declare function runAutopilotScript(root: string | null, action: string): AutopilotScriptResult;
|