auriga-cli 1.15.2 → 1.17.0
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 +14 -2
- package/README.zh-CN.md +14 -2
- package/dist/api-types.d.ts +115 -0
- package/dist/api-types.js +4 -0
- package/dist/apply-handlers.d.ts +17 -0
- package/dist/apply-handlers.js +186 -0
- package/dist/catalog.json +3 -3
- package/dist/cli.d.ts +13 -0
- package/dist/cli.js +220 -0
- package/dist/help.js +2 -0
- package/dist/hooks.d.ts +30 -0
- package/dist/hooks.js +89 -0
- package/dist/plugins.d.ts +29 -0
- package/dist/plugins.js +137 -6
- package/dist/scan-catalog.d.ts +2 -0
- package/dist/scan-catalog.js +138 -0
- package/dist/server.d.ts +71 -0
- package/dist/server.js +759 -0
- package/dist/skills.d.ts +29 -0
- package/dist/skills.js +146 -3
- package/dist/state.d.ts +63 -0
- package/dist/state.js +623 -0
- package/dist/ui-fetch.d.ts +29 -0
- package/dist/ui-fetch.js +267 -0
- package/dist/utils.d.ts +22 -0
- package/dist/utils.js +58 -1
- package/dist/workflow.d.ts +22 -0
- package/dist/workflow.js +63 -0
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ This repo itself is a fully configured harness project. You can clone it to see
|
|
|
11
11
|
| Module | Description |
|
|
12
12
|
|---|---|
|
|
13
13
|
| **Workflow** | `CLAUDE.md` auriga workflow: requirement clarification -> TDD -> Review, Harness principles, Subagent usage guide |
|
|
14
|
-
| **Skills** | Development process + orchestration skills — brainstorming, systematic-debugging, TDD, verification, planning, playwright, test-designer,
|
|
14
|
+
| **Skills** | Development process + orchestration skills — brainstorming, systematic-debugging, TDD, verification, planning, playwright, test-designer, incremental-impl |
|
|
15
15
|
| **Recommended Skills** | Optional utility skills (e.g. `codex-agent`, `claude-code-agent`) you can add on top of the workflow skills |
|
|
16
16
|
| **Plugins** | Recommended Claude Code and Codex plugins — skill-creator, claude-md-management, codex, auriga-go, auriga-git-guards, session-instructions-loader, deep-review |
|
|
17
17
|
| **Hooks** | Claude Code hooks: `notify` (macOS notification, focus-aware sound-only when terminal is frontmost — **opt-in**: not installed by `install --all`, requires `install hooks --hook notify`) |
|
|
@@ -50,6 +50,18 @@ npx -y auriga-cli --help # full catalog + flags
|
|
|
50
50
|
|
|
51
51
|
Exit codes: `0` success, `1` fatal (precheck / parse / fetch), `2` partial success — `stderr` lists per-category `[OK]/[FAIL]` and a `Retry:` hint. After install, reload the Claude Code or Codex session so the new `CLAUDE.md` / skills / plugins / hook registrations are picked up.
|
|
52
52
|
|
|
53
|
+
### Web UI (opt-in)
|
|
54
|
+
|
|
55
|
+
For a browser-based view of what's installed and one-click apply, run:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
npx auriga-cli web-ui
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
This boots a local server on `127.0.0.1`, opens your default browser, and serves a dashboard that scans the current project, shows each module's status (installed / update-available / not-installed), and applies install / update / uninstall in a queue with live SSE progress. The server shuts down on its own ~15 s after the browser closes.
|
|
62
|
+
|
|
63
|
+
The UI is opt-in — `npx auriga-cli` still launches the TTY menu below.
|
|
64
|
+
|
|
53
65
|
### Interactive menu
|
|
54
66
|
|
|
55
67
|
```bash
|
|
@@ -91,7 +103,7 @@ Installs selected skills via `npx skills add`, targeting both Claude Code and Co
|
|
|
91
103
|
| planning-with-files | [OthmanAdi/planning-with-files](https://github.com/OthmanAdi/planning-with-files) | File-based task planning and progress tracking |
|
|
92
104
|
| playwright-cli | [microsoft/playwright-cli](https://github.com/microsoft/playwright-cli) | Browser automation and testing |
|
|
93
105
|
| test-designer | [Ben2pc/auriga-cli](https://github.com/Ben2pc/auriga-cli) | Independent-Evaluation test designer for TDD red phase |
|
|
94
|
-
|
|
|
106
|
+
| incremental-impl | [Ben2pc/auriga-cli](https://github.com/Ben2pc/auriga-cli) | Decides how to implement a non-trivial change: size, slicing strategy, optional parallel dispatch, per-slice execution discipline |
|
|
95
107
|
| session-compound | [Ben2pc/auriga-cli](https://github.com/Ben2pc/auriga-cli) | Post-merge session compounder — distills the session into an interactive HTML report (timeline + token / cache / tool health + playground for skill installs / AGENTS.md edits / new-skill gaps) |
|
|
96
108
|
|
|
97
109
|
**Recommended Skills (opt-in, not installed by `--all`):**
|
package/README.zh-CN.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
| 模块 | 说明 |
|
|
12
12
|
|---|---|
|
|
13
13
|
| **Workflow** | `CLAUDE.md` 里的 auriga 工作流:需求澄清 → TDD → Review,Harness 原则,Subagent 使用指南 |
|
|
14
|
-
| **Skills** | 开发流程 + 编排类 skills —— brainstorming、systematic-debugging、TDD、verification、planning、playwright、test-designer、
|
|
14
|
+
| **Skills** | 开发流程 + 编排类 skills —— brainstorming、systematic-debugging、TDD、verification、planning、playwright、test-designer、incremental-impl |
|
|
15
15
|
| **Recommended Skills** | 可选的工具类 skills(如 `codex-agent`、`claude-code-agent`),在 workflow skills 之外按需追加 |
|
|
16
16
|
| **Plugins** | 推荐的 Claude Code 和 Codex 插件 —— skill-creator、claude-md-management、codex、auriga-go、auriga-git-guards、session-instructions-loader、deep-review |
|
|
17
17
|
| **Hooks** | Claude Code hooks:`notify`(macOS 通知,终端在焦点时仅放声不弹横幅 —— **opt-in**:`install --all` 不装,需要 `install hooks --hook notify`) |
|
|
@@ -50,6 +50,18 @@ npx -y auriga-cli --help # 完整 catalog + flag 说明
|
|
|
50
50
|
|
|
51
51
|
退出码:`0` 成功;`1` 致命错误(前置检查 / 解析 / 拉取失败);`2` 部分成功——`stderr` 会列出逐类 `[OK]/[FAIL]` 和 `Retry:` 提示。装完后请重启 Claude Code 或 Codex 会话,让新的 `CLAUDE.md` / skills / plugins / hook 注册生效。
|
|
52
52
|
|
|
53
|
+
### Web UI(可选)
|
|
54
|
+
|
|
55
|
+
如果想在浏览器里看到“已装 / 可更新 / 未装”全景并一键 apply,跑:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
npx auriga-cli web-ui
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
它会在 `127.0.0.1` 起一个本地 server、自动开浏览器,扫描当前项目并展示 5 个分类的状态。勾选要安装/更新/卸载的项目后点 Apply,SSE 实时回传执行进度。关浏览器后约 15 秒 server 自动退出。
|
|
62
|
+
|
|
63
|
+
Web UI 是显式入口;`npx auriga-cli` 仍然走下面的 TTY 菜单。
|
|
64
|
+
|
|
53
65
|
### 交互式菜单
|
|
54
66
|
|
|
55
67
|
```bash
|
|
@@ -91,7 +103,7 @@ npx auriga-cli
|
|
|
91
103
|
| planning-with-files | [OthmanAdi/planning-with-files](https://github.com/OthmanAdi/planning-with-files) | 文件化任务计划与进度跟踪 |
|
|
92
104
|
| playwright-cli | [microsoft/playwright-cli](https://github.com/microsoft/playwright-cli) | 浏览器自动化与测试 |
|
|
93
105
|
| test-designer | [Ben2pc/auriga-cli](https://github.com/Ben2pc/auriga-cli) | TDD 红灯阶段的 Independent Evaluation 测试设计器 |
|
|
94
|
-
|
|
|
106
|
+
| incremental-impl | [Ben2pc/auriga-cli](https://github.com/Ben2pc/auriga-cli) | 决定如何实现非平凡改动:估算大小、选择切片策略、按需并行派遣、执行片间纪律 |
|
|
95
107
|
| session-compound | [Ben2pc/auriga-cli](https://github.com/Ben2pc/auriga-cli) | PR 合并后的会话复利 skill — 将本次会话沉淀为交互式 HTML 报告(时间线 + token / cache / 工具健康度 + playground:skill 安装 / AGENTS.md 修改 / 新建 skill 缺口) |
|
|
96
108
|
|
|
97
109
|
**Recommended Skills(可选,不在 `--all` 内):**
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
export type ItemStatus = "installed" | "update-available" | "not-installed";
|
|
2
|
+
export interface StateReport {
|
|
3
|
+
/** Absolute path to the project the server was launched against. Surfaced
|
|
4
|
+
* in the UI's top bar so users know where Apply will write project-scope
|
|
5
|
+
* changes. The path may be redacted (e.g. `~/...` home expansion) but the
|
|
6
|
+
* contract is "human-readable identifier for the current cwd". */
|
|
7
|
+
cwd: string;
|
|
8
|
+
workflow: WorkflowState;
|
|
9
|
+
skills: SkillState[];
|
|
10
|
+
recommendedSkills: SkillState[];
|
|
11
|
+
plugins: PluginState[];
|
|
12
|
+
hooks: HookState[];
|
|
13
|
+
warnings: StateWarning[];
|
|
14
|
+
}
|
|
15
|
+
export interface WorkflowState {
|
|
16
|
+
status: ItemStatus;
|
|
17
|
+
currentVersion?: string;
|
|
18
|
+
expectedVersion: string;
|
|
19
|
+
}
|
|
20
|
+
export interface SkillState {
|
|
21
|
+
name: string;
|
|
22
|
+
description: string;
|
|
23
|
+
status: ItemStatus;
|
|
24
|
+
isWorkflow: boolean;
|
|
25
|
+
currentHash?: string;
|
|
26
|
+
expectedHash: string;
|
|
27
|
+
}
|
|
28
|
+
export type ApplyAgent = "claude" | "codex";
|
|
29
|
+
export interface PluginState {
|
|
30
|
+
id: string;
|
|
31
|
+
description: string;
|
|
32
|
+
status: ItemStatus;
|
|
33
|
+
/** Which Agent runtimes this plugin can install into. Most plugins target
|
|
34
|
+
* a single agent; dual-Agent plugins (e.g. auriga-go) have both. When
|
|
35
|
+
* `agents.length === 2` the UI shows a BOTH badge and Apply installs to
|
|
36
|
+
* each agent in turn. Status is aggregated across all targeted agents:
|
|
37
|
+
* `installed` ⇔ all agents installed; `not-installed` ⇔ all not-installed;
|
|
38
|
+
* any partial state (one side installed, other not) → `update-available`
|
|
39
|
+
* so a single Apply backfills the missing side. */
|
|
40
|
+
agents: ApplyAgent[];
|
|
41
|
+
currentVersion?: string;
|
|
42
|
+
expectedVersion?: string;
|
|
43
|
+
versionSource: "upstream-live" | "catalog";
|
|
44
|
+
}
|
|
45
|
+
export interface HookState {
|
|
46
|
+
name: string;
|
|
47
|
+
description: string;
|
|
48
|
+
status: ItemStatus;
|
|
49
|
+
currentHash?: string;
|
|
50
|
+
expectedHash: string;
|
|
51
|
+
}
|
|
52
|
+
export interface StateWarning {
|
|
53
|
+
code: "claude-cli-missing" | "codex-cli-missing" | "marketplace-offline";
|
|
54
|
+
message: string;
|
|
55
|
+
}
|
|
56
|
+
export type ApplyCategory = "workflow" | "skill" | "recommended-skill" | "plugin" | "hook";
|
|
57
|
+
export type ApplyAction = "install" | "update" | "uninstall";
|
|
58
|
+
/**
|
|
59
|
+
* Installer scope. Carried per-item so the Web UI can mix scopes within a
|
|
60
|
+
* single apply batch.
|
|
61
|
+
*
|
|
62
|
+
* - workflow: no scope; field MUST be omitted.
|
|
63
|
+
* - skill / recommended-skill / plugin: "project" | "user". Default project.
|
|
64
|
+
* - hook: "project" | "user" for v0.1 (project-local deferred to v0.2).
|
|
65
|
+
*/
|
|
66
|
+
export type ApplyScope = "project" | "user";
|
|
67
|
+
/**
|
|
68
|
+
* Workflow CLAUDE.md language variant.
|
|
69
|
+
*
|
|
70
|
+
* - "en": English CLAUDE.md (the default).
|
|
71
|
+
* - "zh-CN": Simplified Chinese CLAUDE.md (the localized variant).
|
|
72
|
+
*
|
|
73
|
+
* Only meaningful for `category === "workflow"`; rejected for other
|
|
74
|
+
* categories so the API surface stays explicit.
|
|
75
|
+
*/
|
|
76
|
+
export type ApplyLang = "en" | "zh-CN";
|
|
77
|
+
export interface ApplyItemRef {
|
|
78
|
+
category: ApplyCategory;
|
|
79
|
+
name: string;
|
|
80
|
+
action: ApplyAction;
|
|
81
|
+
/** Installer scope. Omitted = "project" (back-compat default). The server
|
|
82
|
+
* rejects this field for category="workflow" because workflow has no
|
|
83
|
+
* scope concept (it's a single file at the project root). */
|
|
84
|
+
scope?: ApplyScope;
|
|
85
|
+
/** Workflow CLAUDE.md language variant. Omitted = "en" (back-compat
|
|
86
|
+
* default). The server rejects this field for any non-workflow
|
|
87
|
+
* category. */
|
|
88
|
+
lang?: ApplyLang;
|
|
89
|
+
}
|
|
90
|
+
export interface ApplyRequest {
|
|
91
|
+
items: ApplyItemRef[];
|
|
92
|
+
}
|
|
93
|
+
export interface ApplyResponse {
|
|
94
|
+
jobId: string;
|
|
95
|
+
}
|
|
96
|
+
export type ProgressEvent = {
|
|
97
|
+
type: "item:start";
|
|
98
|
+
index: number;
|
|
99
|
+
total: number;
|
|
100
|
+
item: ApplyItemRef;
|
|
101
|
+
} | {
|
|
102
|
+
type: "item:log";
|
|
103
|
+
index: number;
|
|
104
|
+
line: string;
|
|
105
|
+
level: "info" | "warn" | "error";
|
|
106
|
+
} | {
|
|
107
|
+
type: "item:done";
|
|
108
|
+
index: number;
|
|
109
|
+
success: boolean;
|
|
110
|
+
error?: string;
|
|
111
|
+
} | {
|
|
112
|
+
type: "all-done";
|
|
113
|
+
success: boolean;
|
|
114
|
+
failedCount: number;
|
|
115
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ApplyLang } from "./api-types.js";
|
|
2
|
+
import type { ApplyHandlers } from "./server.js";
|
|
3
|
+
export interface ApplyHandlerContext {
|
|
4
|
+
/** Where auriga-cli lives — source of skills-lock.json + .claude config. */
|
|
5
|
+
packageRoot: string;
|
|
6
|
+
/** Target project directory. Installers write here. */
|
|
7
|
+
cwd: string;
|
|
8
|
+
/** Resolves plugin name → the list of agents this plugin can install
|
|
9
|
+
* into. Built at boot from the same scan catalog the /api/state route
|
|
10
|
+
* uses. dual-Agent plugins (e.g. `auriga-go`) yield `["claude","codex"]`
|
|
11
|
+
* and the handler iterates the list, installing to each agent in turn.
|
|
12
|
+
* Names not in the map default to `["claude"]` (existing CLI default). */
|
|
13
|
+
pluginAgentsByName: Map<string, ("claude" | "codex")[]>;
|
|
14
|
+
/** Workflow language for install. Defaults to "en". */
|
|
15
|
+
workflowLang?: ApplyLang;
|
|
16
|
+
}
|
|
17
|
+
export declare function buildDefaultApplyHandlers(ctx: ApplyHandlerContext): ApplyHandlers;
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
// Builds the default ApplyHandlers map that wires the Web UI's /api/apply
|
|
2
|
+
// route to the real installers in workflow.ts / skills.ts / plugins.ts /
|
|
3
|
+
// hooks.ts. Tests inject their own mock handlers; CLI mode (the `web-ui`
|
|
4
|
+
// subcommand) calls `buildDefaultApplyHandlers` at boot.
|
|
5
|
+
//
|
|
6
|
+
// Per-item dispatch is layered on top of the existing bulk installers via
|
|
7
|
+
// `opts.selected = [name]`. The recipe per category:
|
|
8
|
+
//
|
|
9
|
+
// workflow: installWorkflow(packageRoot, …) ─┐
|
|
10
|
+
// workflow: uninstallWorkflow({force:true,…})│ no name needed
|
|
11
|
+
// skill: installSkills(…, selected:[name])│
|
|
12
|
+
// skill: uninstallSkill(name, …) │
|
|
13
|
+
// recommended-skill: installRecommendedSkills(…) │
|
|
14
|
+
// recommended-skill: uninstallSkill(name, …) │ same store
|
|
15
|
+
// plugin: installPlugins(…, agent, sel:[]) │ per-name
|
|
16
|
+
// plugin: uninstallPlugin(name, agent, …) │
|
|
17
|
+
// hook: installHook(hookDef, "project",…)│ needs HookDef
|
|
18
|
+
// hook: uninstallHook(name, …) │
|
|
19
|
+
//
|
|
20
|
+
// Spec: docs/architecture/web-ui.md §6.4 (apply execution model).
|
|
21
|
+
import { installHook, loadHooksConfig, uninstallHook } from "./hooks.js";
|
|
22
|
+
import { installPlugins, uninstallPlugin, } from "./plugins.js";
|
|
23
|
+
import { installRecommendedSkills, installSkills, uninstallSkill, } from "./skills.js";
|
|
24
|
+
import { installWorkflow, uninstallWorkflow } from "./workflow.js";
|
|
25
|
+
const ALL_ACTIONS = new Set([
|
|
26
|
+
"install",
|
|
27
|
+
"update",
|
|
28
|
+
"uninstall",
|
|
29
|
+
]);
|
|
30
|
+
function assertAction(action) {
|
|
31
|
+
// Defense in depth — the server validates the shape already, but the
|
|
32
|
+
// adapter must not silently fall through if a new action is added later.
|
|
33
|
+
if (!ALL_ACTIONS.has(action)) {
|
|
34
|
+
throw new Error(`unsupported action: ${action}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export function buildDefaultApplyHandlers(ctx) {
|
|
38
|
+
const { packageRoot, cwd, pluginAgentsByName } = ctx;
|
|
39
|
+
const lang = ctx.workflowLang ?? "en";
|
|
40
|
+
const workflow = async (action, _name, { onLog, lang: requestedLang }) => {
|
|
41
|
+
assertAction(action);
|
|
42
|
+
// Per-item lang overrides the ctx default (the UI now drives this via
|
|
43
|
+
// the Workflow column's EN/ZH-CN picker). Falls back to ctx lang for
|
|
44
|
+
// CLI-mode callers that don't pass it.
|
|
45
|
+
const installLang = requestedLang ?? lang;
|
|
46
|
+
if (action === "install" || action === "update") {
|
|
47
|
+
await installWorkflow(packageRoot, {
|
|
48
|
+
interactive: false,
|
|
49
|
+
cwd,
|
|
50
|
+
lang: installLang,
|
|
51
|
+
});
|
|
52
|
+
onLog(`workflow installed (${installLang})`, "info");
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
// uninstall
|
|
56
|
+
await uninstallWorkflow({
|
|
57
|
+
force: true,
|
|
58
|
+
cwd,
|
|
59
|
+
onLog: (line) => onLog(line, "info"),
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
// Adapter from InstallOpts.onLog (stdout|stderr) → handler's onLog
|
|
63
|
+
// (info|warn|error). stderr lines surface as warnings; the SSE consumer
|
|
64
|
+
// can decide whether to render them differently.
|
|
65
|
+
const streamLog = (onLog) => (line, stream) => {
|
|
66
|
+
onLog(line, stream === "stderr" ? "warn" : "info");
|
|
67
|
+
};
|
|
68
|
+
const skill = async (action, name, { onLog, scope }) => {
|
|
69
|
+
assertAction(action);
|
|
70
|
+
const installScope = scope ?? "project";
|
|
71
|
+
if (action === "install" || action === "update") {
|
|
72
|
+
await installSkills(packageRoot, {
|
|
73
|
+
interactive: false,
|
|
74
|
+
cwd,
|
|
75
|
+
selected: [name],
|
|
76
|
+
scope: installScope,
|
|
77
|
+
onLog: streamLog(onLog),
|
|
78
|
+
});
|
|
79
|
+
onLog(`skill ${name} installed (${installScope})`, "info");
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
await uninstallSkill(name, {
|
|
83
|
+
cwd,
|
|
84
|
+
scope: installScope,
|
|
85
|
+
onLog: (line) => onLog(line, "info"),
|
|
86
|
+
});
|
|
87
|
+
};
|
|
88
|
+
const recommendedSkill = async (action, name, { onLog, scope }) => {
|
|
89
|
+
assertAction(action);
|
|
90
|
+
const installScope = scope ?? "project";
|
|
91
|
+
if (action === "install" || action === "update") {
|
|
92
|
+
await installRecommendedSkills(packageRoot, {
|
|
93
|
+
interactive: false,
|
|
94
|
+
cwd,
|
|
95
|
+
selected: [name],
|
|
96
|
+
scope: installScope,
|
|
97
|
+
onLog: streamLog(onLog),
|
|
98
|
+
});
|
|
99
|
+
onLog(`recommended skill ${name} installed (${installScope})`, "info");
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
// Uninstall path is the same regardless of workflow vs recommended —
|
|
103
|
+
// both live in skills-lock.json + .claude/skills/<name>.
|
|
104
|
+
await uninstallSkill(name, {
|
|
105
|
+
cwd,
|
|
106
|
+
scope: installScope,
|
|
107
|
+
onLog: (line) => onLog(line, "info"),
|
|
108
|
+
});
|
|
109
|
+
};
|
|
110
|
+
const plugin = async (action, name, { onLog, scope }) => {
|
|
111
|
+
assertAction(action);
|
|
112
|
+
const agents = pluginAgentsByName.get(name) ?? ["claude"];
|
|
113
|
+
const installScope = scope ?? "project";
|
|
114
|
+
// dual-Agent plugins (length === 2) install into each agent in turn.
|
|
115
|
+
// Per-agent try/catch: if Claude install fails, still try Codex so
|
|
116
|
+
// partial coverage is visible to the user. Failures are aggregated
|
|
117
|
+
// and thrown at the end → SSE marks the item failed but onLog
|
|
118
|
+
// shows both agent outcomes.
|
|
119
|
+
const failures = [];
|
|
120
|
+
for (const agent of agents) {
|
|
121
|
+
try {
|
|
122
|
+
if (action === "install" || action === "update") {
|
|
123
|
+
await installPlugins(packageRoot, {
|
|
124
|
+
interactive: false,
|
|
125
|
+
cwd,
|
|
126
|
+
agent,
|
|
127
|
+
selected: [name],
|
|
128
|
+
scope: installScope,
|
|
129
|
+
onLog: streamLog(onLog),
|
|
130
|
+
});
|
|
131
|
+
onLog(`plugin ${name} installed (${agent}, ${installScope})`, "info");
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
await uninstallPlugin(name, agent, {
|
|
135
|
+
cwd,
|
|
136
|
+
onLog: (line) => onLog(`[${agent}] ${line}`, "info"),
|
|
137
|
+
});
|
|
138
|
+
onLog(`plugin ${name} uninstalled (${agent})`, "info");
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
143
|
+
failures.push({ agent, error });
|
|
144
|
+
onLog(`plugin ${name} ${action} failed (${agent}): ${error.message}`, "error");
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
if (failures.length > 0) {
|
|
148
|
+
const summary = failures
|
|
149
|
+
.map((f) => `${f.agent}: ${f.error.message}`)
|
|
150
|
+
.join("; ");
|
|
151
|
+
throw new Error(`plugin ${name} ${action} failed for ${failures.length} agent(s) — ${summary}`);
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
const hook = async (action, name, { onLog, scope }) => {
|
|
155
|
+
assertAction(action);
|
|
156
|
+
const installScope = scope ?? "project";
|
|
157
|
+
if (action === "uninstall") {
|
|
158
|
+
await uninstallHook(name, {
|
|
159
|
+
cwd,
|
|
160
|
+
scope: installScope,
|
|
161
|
+
onLog: (line) => onLog(line, "info"),
|
|
162
|
+
});
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
// install + update both run installHook with the requested scope. The
|
|
166
|
+
// hook installer is idempotent — re-running == "update". Look up the
|
|
167
|
+
// HookDef in the bundled registry; unknown name → loud throw so the
|
|
168
|
+
// SSE caller surfaces it as item:done success=false.
|
|
169
|
+
const config = loadHooksConfig(packageRoot);
|
|
170
|
+
const hookDef = config.hooks.find((h) => h.name === name);
|
|
171
|
+
if (!hookDef) {
|
|
172
|
+
throw new Error(`hook not found in registry: ${name}`);
|
|
173
|
+
}
|
|
174
|
+
// installHook takes a wider Scope union ("project"|"user"|"project-local");
|
|
175
|
+
// v0.1 only exposes "project"|"user" via the API. Cast is safe.
|
|
176
|
+
await installHook(hookDef, scope ?? "project", cwd, packageRoot);
|
|
177
|
+
onLog(`hook ${name} installed (${scope ?? "project"})`, "info");
|
|
178
|
+
};
|
|
179
|
+
return {
|
|
180
|
+
workflow,
|
|
181
|
+
skill,
|
|
182
|
+
"recommended-skill": recommendedSkill,
|
|
183
|
+
plugin,
|
|
184
|
+
hook,
|
|
185
|
+
};
|
|
186
|
+
}
|
package/dist/catalog.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
|
-
"generatedAt": "2026-05-
|
|
2
|
+
"generatedAt": "2026-05-12T11:30:47.843Z",
|
|
3
3
|
"workflowSkills": [
|
|
4
4
|
{
|
|
5
5
|
"name": "brainstorming",
|
|
6
6
|
"description": "You MUST use this before any creative work - creating features, building components, adding functionality, or modifying behavior. Explores user intent, requirements and design before implementation."
|
|
7
7
|
},
|
|
8
8
|
{
|
|
9
|
-
"name": "
|
|
10
|
-
"description": "Plan
|
|
9
|
+
"name": "incremental-impl",
|
|
10
|
+
"description": "Plan a non-trivial code change end-to-end — size triage (XS–XL), slicing strategy, optional parallel subagent dispatch, per-slice Implement → Test → Verify → Commit discipline. Use for any multi-file change, refactor across files, executing a planned task from any planning source, cross-cutting modification (analytics sweep / i18n / library migration), or when about to write more than ~100 lines. 也用于增量实现 / 切片落地 / 推进已规划任务 / 跨切面改动。Skip only for trivial XS edits and pure documentation / configuration changes."
|
|
11
11
|
},
|
|
12
12
|
{
|
|
13
13
|
"name": "planning-with-files",
|
package/dist/cli.d.ts
CHANGED
|
@@ -11,6 +11,16 @@ export interface InstallParsed {
|
|
|
11
11
|
scope?: "project" | "user";
|
|
12
12
|
agent?: PluginAgent;
|
|
13
13
|
}
|
|
14
|
+
export interface UiParsed {
|
|
15
|
+
/** Override the default port (4747). When set, the fallback range is
|
|
16
|
+
* also skipped — we either succeed on this port or fail. */
|
|
17
|
+
port?: number;
|
|
18
|
+
/** Override ui-fetch; serve from this local directory instead. Useful
|
|
19
|
+
* for development against `ui/dist` without a release tag. */
|
|
20
|
+
uiDir?: string;
|
|
21
|
+
/** Skip opening the browser. Prints the URL only. */
|
|
22
|
+
noOpen?: boolean;
|
|
23
|
+
}
|
|
14
24
|
export type ParsedArgs = {
|
|
15
25
|
command: "help";
|
|
16
26
|
helpType?: CategoryName;
|
|
@@ -21,6 +31,9 @@ export type ParsedArgs = {
|
|
|
21
31
|
} | {
|
|
22
32
|
command: "install";
|
|
23
33
|
install: InstallParsed;
|
|
34
|
+
} | {
|
|
35
|
+
command: "web-ui";
|
|
36
|
+
ui: UiParsed;
|
|
24
37
|
};
|
|
25
38
|
export declare function parseArgs(argv: string[]): ParsedArgs;
|
|
26
39
|
export declare function main(argv: string[]): Promise<number>;
|