@cjhyy/code-shell-core 0.5.0-rc.0 → 0.5.0-rc.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/dist/agent/agent-definition-registry.d.ts +29 -0
- package/dist/agent/agent-definition-registry.js +74 -0
- package/dist/agent/agent-definition.d.ts +37 -0
- package/dist/agent/agent-definition.js +59 -0
- package/dist/arena/arena.js +11 -12
- package/dist/arena/context/context-tools.js +2 -4
- package/dist/arena/context/within-root.d.ts +7 -0
- package/dist/arena/context/within-root.js +15 -0
- package/dist/arena/iterate/phases/argue.js +8 -2
- package/dist/arena/iterate/phases/revise.js +1 -1
- package/dist/arena/iterate/phases/tournament.js +3 -3
- package/dist/arena/phases/adjudication.js +1 -4
- package/dist/arena/phases/build-consensus.js +1 -4
- package/dist/arena/phases/cross-review.js +2 -8
- package/dist/arena/phases/debate-rounds.js +1 -4
- package/dist/arena/phases/participant-research.js +1 -4
- package/dist/arena/phases/planning-detail-expansion.js +8 -10
- package/dist/arena/planner.js +0 -1
- package/dist/arena/providers/docs.d.ts +1 -0
- package/dist/arena/providers/docs.js +5 -2
- package/dist/arena/providers/repo.d.ts +1 -0
- package/dist/arena/providers/repo.js +5 -2
- package/dist/arena/strategies/utils.js +36 -3
- package/dist/arena/transitions.d.ts +7 -2
- package/dist/arena/transitions.js +9 -4
- package/dist/arena/types.d.ts +8 -2
- package/dist/automation/cron-expr.d.ts +31 -0
- package/dist/automation/cron-expr.js +151 -0
- package/dist/automation/index.d.ts +41 -0
- package/dist/automation/index.js +39 -0
- package/dist/automation/runner.d.ts +67 -0
- package/dist/automation/runner.js +56 -0
- package/dist/automation/scheduler.d.ts +156 -0
- package/dist/automation/scheduler.js +546 -0
- package/dist/automation/store.d.ts +39 -0
- package/dist/automation/store.js +119 -0
- package/dist/automation/write-policy.d.ts +34 -0
- package/dist/automation/write-policy.js +113 -0
- package/dist/automation/write-run.d.ts +51 -0
- package/dist/automation/write-run.js +38 -0
- package/dist/capability-control/index.d.ts +5 -0
- package/dist/capability-control/index.js +3 -0
- package/dist/capability-control/overlay.d.ts +49 -0
- package/dist/capability-control/overlay.js +89 -0
- package/dist/capability-control/project.d.ts +65 -0
- package/dist/capability-control/project.js +147 -0
- package/dist/capability-control/service.d.ts +70 -0
- package/dist/capability-control/service.js +147 -0
- package/dist/capability-control/types.d.ts +62 -0
- package/dist/capability-control/types.js +17 -0
- package/dist/cli/agent-server-stdio.d.ts +12 -1
- package/dist/cli/agent-server-stdio.js +118 -18
- package/dist/cli/agent-server-tcp.d.ts +20 -0
- package/dist/cli/agent-server-tcp.js +120 -0
- package/dist/cli/graceful-shutdown.d.ts +27 -0
- package/dist/cli/graceful-shutdown.js +30 -0
- package/dist/context/compaction.js +23 -15
- package/dist/context/manager.d.ts +0 -20
- package/dist/context/manager.js +0 -37
- package/dist/cron/cron-runtime.d.ts +2 -0
- package/dist/cron/cron-runtime.js +2 -0
- package/dist/cron/cron-store.d.ts +2 -0
- package/dist/cron/cron-store.js +2 -0
- package/dist/cron/scheduler.d.ts +5 -32
- package/dist/cron/scheduler.js +5 -113
- package/dist/data/openrouter-sync.js +1 -1
- package/dist/engine/engine.d.ts +256 -16
- package/dist/engine/engine.js +856 -200
- package/dist/engine/goal.d.ts +42 -0
- package/dist/engine/goal.js +52 -0
- package/dist/engine/image-compression.d.ts +81 -0
- package/dist/engine/image-compression.js +186 -0
- package/dist/engine/image-policy.d.ts +152 -0
- package/dist/engine/image-policy.js +165 -0
- package/dist/engine/reactive-threshold.d.ts +13 -0
- package/dist/engine/reactive-threshold.js +17 -0
- package/dist/engine/runtime.js +7 -0
- package/dist/engine/session-title.d.ts +13 -0
- package/dist/engine/session-title.js +34 -0
- package/dist/engine/turn-loop.d.ts +29 -8
- package/dist/engine/turn-loop.js +498 -316
- package/dist/git/parse-log.d.ts +13 -0
- package/dist/git/parse-log.js +21 -0
- package/dist/git/utils.d.ts +8 -6
- package/dist/git/utils.js +57 -26
- package/dist/git/worktree.js +33 -18
- package/dist/hooks/events.d.ts +23 -1
- package/dist/hooks/goal-stop-hook.d.ts +30 -0
- package/dist/hooks/goal-stop-hook.js +102 -0
- package/dist/hooks/hook-output.d.ts +33 -0
- package/dist/hooks/hook-output.js +79 -0
- package/dist/hooks/registry.d.ts +7 -0
- package/dist/hooks/registry.js +38 -1
- package/dist/hooks/shell-runner.d.ts +2 -0
- package/dist/hooks/shell-runner.js +43 -2
- package/dist/index.d.ts +32 -7
- package/dist/index.js +30 -3
- package/dist/llm/capabilities/reasoning-control.d.ts +24 -0
- package/dist/llm/capabilities/reasoning-control.js +38 -0
- package/dist/llm/capabilities/rules.js +33 -3
- package/dist/llm/capabilities/types.d.ts +22 -2
- package/dist/llm/clamp-max-tokens.d.ts +11 -0
- package/dist/llm/clamp-max-tokens.js +17 -0
- package/dist/llm/client-base.d.ts +41 -4
- package/dist/llm/client-base.js +67 -13
- package/dist/llm/client-factory.d.ts +3 -3
- package/dist/llm/client-factory.js +2 -2
- package/dist/llm/model-pool.d.ts +15 -11
- package/dist/llm/model-pool.js +23 -20
- package/dist/llm/provider-catalog.d.ts +2 -2
- package/dist/llm/providers/anthropic.d.ts +32 -2
- package/dist/llm/providers/anthropic.js +147 -8
- package/dist/llm/providers/openai.d.ts +11 -2
- package/dist/llm/providers/openai.js +253 -52
- package/dist/llm/reasoning-setting.d.ts +51 -0
- package/dist/llm/reasoning-setting.js +32 -0
- package/dist/llm/stop-reason.d.ts +13 -0
- package/dist/llm/stop-reason.js +21 -0
- package/dist/llm/strip-vision.d.ts +32 -0
- package/dist/llm/strip-vision.js +94 -0
- package/dist/llm/types.d.ts +5 -6
- package/dist/logging/logger.js +18 -4
- package/dist/logging/sanitize-messages.d.ts +10 -0
- package/dist/logging/sanitize-messages.js +90 -0
- package/dist/lsp/client.js +28 -8
- package/dist/lsp/manager.js +2 -1
- package/dist/lsp/root-path.d.ts +9 -0
- package/dist/lsp/root-path.js +12 -0
- package/dist/onboarding.js +18 -11
- package/dist/plugins/gitOps.d.ts +34 -0
- package/dist/plugins/gitOps.js +59 -3
- package/dist/plugins/installer/codex/convertAgents.d.ts +7 -0
- package/dist/plugins/installer/codex/convertAgents.js +55 -0
- package/dist/plugins/installer/codex/convertMcp.d.ts +8 -0
- package/dist/plugins/installer/codex/convertMcp.js +45 -0
- package/dist/plugins/installer/codex/convertSkills.d.ts +12 -0
- package/dist/plugins/installer/codex/convertSkills.js +33 -0
- package/dist/plugins/installer/detectFormat.d.ts +2 -0
- package/dist/plugins/installer/detectFormat.js +6 -0
- package/dist/plugins/installer/install.d.ts +7 -0
- package/dist/plugins/installer/install.js +99 -0
- package/dist/plugins/installer/installFromSource.d.ts +13 -0
- package/dist/plugins/installer/installFromSource.js +45 -0
- package/dist/plugins/installer/list.d.ts +9 -0
- package/dist/plugins/installer/list.js +30 -0
- package/dist/plugins/installer/loadPluginAgents.d.ts +3 -0
- package/dist/plugins/installer/loadPluginAgents.js +23 -0
- package/dist/plugins/installer/loadPluginMcp.d.ts +7 -0
- package/dist/plugins/installer/loadPluginMcp.js +74 -0
- package/dist/plugins/installer/parseSource.d.ts +20 -0
- package/dist/plugins/installer/parseSource.js +74 -0
- package/dist/plugins/installer/paths.d.ts +5 -0
- package/dist/plugins/installer/paths.js +25 -0
- package/dist/plugins/installer/types.d.ts +49 -0
- package/dist/plugins/installer/types.js +27 -0
- package/dist/plugins/installer/uninstall.d.ts +2 -0
- package/dist/plugins/installer/uninstall.js +14 -0
- package/dist/plugins/installer/update.d.ts +14 -0
- package/dist/plugins/installer/update.js +65 -0
- package/dist/plugins/loadPluginHooks.d.ts +8 -1
- package/dist/plugins/loadPluginHooks.js +11 -1
- package/dist/plugins/marketplaceManager.d.ts +8 -1
- package/dist/plugins/marketplaceManager.js +38 -4
- package/dist/plugins/pluginCommandHook.js +34 -0
- package/dist/plugins/pluginInstaller.d.ts +21 -0
- package/dist/plugins/pluginInstaller.js +128 -29
- package/dist/plugins/schemas.js +40 -6
- package/dist/plugins/types.d.ts +4 -0
- package/dist/preset/index.js +16 -0
- package/dist/prompt/composer.d.ts +10 -0
- package/dist/prompt/composer.js +29 -4
- package/dist/prompt/sections/orchestration.md +8 -0
- package/dist/protocol/chat-session-manager.d.ts +8 -1
- package/dist/protocol/chat-session-manager.js +10 -0
- package/dist/protocol/chat-session.d.ts +17 -0
- package/dist/protocol/chat-session.js +28 -0
- package/dist/protocol/redact.d.ts +50 -0
- package/dist/protocol/redact.js +71 -0
- package/dist/protocol/server.d.ts +41 -2
- package/dist/protocol/server.js +231 -33
- package/dist/protocol/tcp-transport.d.ts +45 -0
- package/dist/protocol/tcp-transport.js +74 -0
- package/dist/protocol/types.d.ts +23 -0
- package/dist/protocol/types.js +6 -0
- package/dist/remote/bridge.d.ts +11 -2
- package/dist/remote/bridge.js +61 -33
- package/dist/run/ArtifactTracker.js +5 -4
- package/dist/run/EngineRunner.d.ts +27 -1
- package/dist/run/EngineRunner.js +46 -8
- package/dist/run/FileRunStore.js +32 -8
- package/dist/run/RunLock.d.ts +28 -2
- package/dist/run/RunLock.js +49 -7
- package/dist/run/RunManager.js +51 -3
- package/dist/run/RunQueue.d.ts +1 -0
- package/dist/run/RunQueue.js +8 -2
- package/dist/run/factory.d.ts +7 -0
- package/dist/run/factory.js +1 -0
- package/dist/run/index.d.ts +2 -2
- package/dist/run/index.js +1 -1
- package/dist/run/redirect-target.d.ts +7 -0
- package/dist/run/redirect-target.js +13 -0
- package/dist/run/types.js +1 -1
- package/dist/services/browser-open.d.ts +13 -0
- package/dist/services/browser-open.js +16 -0
- package/dist/services/dream-consolidation.d.ts +57 -0
- package/dist/services/dream-consolidation.js +151 -0
- package/dist/services/memory-orchestrator.js +18 -0
- package/dist/services/notifier.d.ts +8 -0
- package/dist/services/notifier.js +39 -25
- package/dist/services/oauth.js +5 -7
- package/dist/services/session-memory-sort.d.ts +8 -0
- package/dist/services/session-memory-sort.js +9 -0
- package/dist/services/session-memory.js +8 -9
- package/dist/session/file-history.js +10 -3
- package/dist/session/session-manager.d.ts +23 -1
- package/dist/session/session-manager.js +73 -2
- package/dist/settings/disk-defaults.d.ts +35 -0
- package/dist/settings/disk-defaults.js +24 -0
- package/dist/settings/manager.d.ts +45 -1
- package/dist/settings/manager.js +121 -17
- package/dist/settings/manager.test.d.ts +1 -0
- package/dist/settings/manager.test.js +73 -0
- package/dist/settings/personalization.d.ts +19 -0
- package/dist/settings/personalization.js +7 -0
- package/dist/settings/schema.d.ts +1163 -126
- package/dist/settings/schema.js +126 -10
- package/dist/skills/scanner.d.ts +13 -6
- package/dist/skills/scanner.js +23 -4
- package/dist/tool-system/builtin/add-marketplace.d.ts +12 -0
- package/dist/tool-system/builtin/add-marketplace.js +76 -0
- package/dist/tool-system/builtin/agent-registry.d.ts +15 -0
- package/dist/tool-system/builtin/agent-registry.js +14 -4
- package/dist/tool-system/builtin/agent.d.ts +55 -0
- package/dist/tool-system/builtin/agent.js +165 -17
- package/dist/tool-system/builtin/apply-patch/index.js +22 -3
- package/dist/tool-system/builtin/arena.js +6 -7
- package/dist/tool-system/builtin/complete-goal.d.ts +25 -0
- package/dist/tool-system/builtin/complete-goal.js +45 -0
- package/dist/tool-system/builtin/cron.js +53 -9
- package/dist/tool-system/builtin/edit.d.ts +2 -1
- package/dist/tool-system/builtin/edit.js +6 -1
- package/dist/tool-system/builtin/generate-image.d.ts +25 -0
- package/dist/tool-system/builtin/generate-image.js +146 -0
- package/dist/tool-system/builtin/glob.js +7 -0
- package/dist/tool-system/builtin/grep.js +6 -0
- package/dist/tool-system/builtin/index.d.ts +18 -1
- package/dist/tool-system/builtin/index.js +62 -1
- package/dist/tool-system/builtin/notebook-edit.d.ts +2 -1
- package/dist/tool-system/builtin/notebook-edit.js +8 -1
- package/dist/tool-system/builtin/read.d.ts +2 -1
- package/dist/tool-system/builtin/read.js +9 -1
- package/dist/tool-system/builtin/skill.js +23 -5
- package/dist/tool-system/builtin/sleep.js +9 -3
- package/dist/tool-system/builtin/task.js +4 -1
- package/dist/tool-system/builtin/update-automation-memory.d.ts +24 -0
- package/dist/tool-system/builtin/update-automation-memory.js +60 -0
- package/dist/tool-system/builtin/view-image.d.ts +18 -0
- package/dist/tool-system/builtin/view-image.js +96 -0
- package/dist/tool-system/builtin/web-search.d.ts +4 -1
- package/dist/tool-system/builtin/web-search.js +36 -3
- package/dist/tool-system/builtin/write.d.ts +2 -1
- package/dist/tool-system/builtin/write.js +7 -1
- package/dist/tool-system/context.d.ts +43 -0
- package/dist/tool-system/executor.d.ts +0 -1
- package/dist/tool-system/executor.js +34 -40
- package/dist/tool-system/investigation-guard.d.ts +4 -1
- package/dist/tool-system/investigation-guard.js +19 -3
- package/dist/tool-system/mcp-manager.d.ts +36 -12
- package/dist/tool-system/mcp-manager.js +173 -10
- package/dist/tool-system/path-policy.d.ts +94 -0
- package/dist/tool-system/path-policy.js +279 -0
- package/dist/tool-system/permission.js +43 -50
- package/dist/tool-system/plan-mode-allowlist.d.ts +21 -0
- package/dist/tool-system/plan-mode-allowlist.js +43 -0
- package/dist/tool-system/registry.js +12 -1
- package/dist/tool-system/validation.d.ts +10 -0
- package/dist/tool-system/validation.js +16 -3
- package/dist/types.d.ts +90 -15
- package/dist/utils/format.js +4 -2
- package/dist/utils/lockfile.js +9 -2
- package/dist/utils/theme.d.ts +6 -0
- package/dist/utils/theme.js +4 -2
- package/package.json +2 -1
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** Codex `.codex-plugin/plugin.json`. v1 reads required fields; unknowns pass through. */
|
|
3
|
+
export declare const CodexPluginManifest: z.ZodObject<{
|
|
4
|
+
name: z.ZodString;
|
|
5
|
+
version: z.ZodString;
|
|
6
|
+
description: z.ZodOptional<z.ZodString>;
|
|
7
|
+
mcpServers: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodRecord<z.ZodString, z.ZodAny>]>>;
|
|
8
|
+
skills: z.ZodOptional<z.ZodString>;
|
|
9
|
+
agents: z.ZodOptional<z.ZodString>;
|
|
10
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
11
|
+
name: z.ZodString;
|
|
12
|
+
version: z.ZodString;
|
|
13
|
+
description: z.ZodOptional<z.ZodString>;
|
|
14
|
+
mcpServers: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodRecord<z.ZodString, z.ZodAny>]>>;
|
|
15
|
+
skills: z.ZodOptional<z.ZodString>;
|
|
16
|
+
agents: z.ZodOptional<z.ZodString>;
|
|
17
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
18
|
+
name: z.ZodString;
|
|
19
|
+
version: z.ZodString;
|
|
20
|
+
description: z.ZodOptional<z.ZodString>;
|
|
21
|
+
mcpServers: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodRecord<z.ZodString, z.ZodAny>]>>;
|
|
22
|
+
skills: z.ZodOptional<z.ZodString>;
|
|
23
|
+
agents: z.ZodOptional<z.ZodString>;
|
|
24
|
+
}, z.ZodTypeAny, "passthrough">>;
|
|
25
|
+
export type CodexPluginManifest = z.infer<typeof CodexPluginManifest>;
|
|
26
|
+
/** `.cs-meta.json` written into every installed plugin dir. */
|
|
27
|
+
export declare const CSMeta: z.ZodObject<{
|
|
28
|
+
name: z.ZodString;
|
|
29
|
+
format: z.ZodEnum<["cc", "codex"]>;
|
|
30
|
+
version: z.ZodOptional<z.ZodString>;
|
|
31
|
+
source: z.ZodString;
|
|
32
|
+
installedAt: z.ZodString;
|
|
33
|
+
}, "strip", z.ZodTypeAny, {
|
|
34
|
+
source: string;
|
|
35
|
+
name: string;
|
|
36
|
+
format: "codex" | "cc";
|
|
37
|
+
installedAt: string;
|
|
38
|
+
version?: string | undefined;
|
|
39
|
+
}, {
|
|
40
|
+
source: string;
|
|
41
|
+
name: string;
|
|
42
|
+
format: "codex" | "cc";
|
|
43
|
+
installedAt: string;
|
|
44
|
+
version?: string | undefined;
|
|
45
|
+
}>;
|
|
46
|
+
export type CSMeta = z.infer<typeof CSMeta>;
|
|
47
|
+
export declare class PluginInstallError extends Error {
|
|
48
|
+
constructor(message: string);
|
|
49
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** Codex `.codex-plugin/plugin.json`. v1 reads required fields; unknowns pass through. */
|
|
3
|
+
export const CodexPluginManifest = z
|
|
4
|
+
.object({
|
|
5
|
+
name: z.string(),
|
|
6
|
+
version: z.string(),
|
|
7
|
+
description: z.string().optional(),
|
|
8
|
+
// string → relative path to a .mcp.json; object → inline mcpServers map
|
|
9
|
+
mcpServers: z.union([z.string(), z.record(z.any())]).optional(),
|
|
10
|
+
skills: z.string().optional(),
|
|
11
|
+
agents: z.string().optional(),
|
|
12
|
+
})
|
|
13
|
+
.passthrough();
|
|
14
|
+
/** `.cs-meta.json` written into every installed plugin dir. */
|
|
15
|
+
export const CSMeta = z.object({
|
|
16
|
+
name: z.string(),
|
|
17
|
+
format: z.enum(["cc", "codex"]),
|
|
18
|
+
version: z.string().optional(),
|
|
19
|
+
source: z.string(),
|
|
20
|
+
installedAt: z.string(),
|
|
21
|
+
});
|
|
22
|
+
export class PluginInstallError extends Error {
|
|
23
|
+
constructor(message) {
|
|
24
|
+
super(message);
|
|
25
|
+
this.name = "PluginInstallError";
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { existsSync, rmSync } from "node:fs";
|
|
2
|
+
import { pluginInstallDir, assertSafePluginName } from "./paths.js";
|
|
3
|
+
import { removeInstallEntries, pluginInstallKey } from "../installedPlugins.js";
|
|
4
|
+
import { PluginInstallError } from "./types.js";
|
|
5
|
+
/** Remove a locally-installed plugin dir + its installed_plugins.json entry. */
|
|
6
|
+
export function uninstallPluginByName(name) {
|
|
7
|
+
assertSafePluginName(name);
|
|
8
|
+
const dir = pluginInstallDir(name);
|
|
9
|
+
if (!existsSync(dir)) {
|
|
10
|
+
throw new PluginInstallError(`no plugin named '${name}'`);
|
|
11
|
+
}
|
|
12
|
+
rmSync(dir, { recursive: true, force: true });
|
|
13
|
+
removeInstallEntries(pluginInstallKey(name, "local"));
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface UpdateResult {
|
|
2
|
+
updated: boolean;
|
|
3
|
+
reason: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Reinstall a plugin from its recorded source.
|
|
7
|
+
*
|
|
8
|
+
* - Local source: reinstall when the source version changed, or when `force`.
|
|
9
|
+
* CC plugins have no version → only `force` updates them.
|
|
10
|
+
* - Remote (git) source: re-clone and reinstall every time — git sources carry
|
|
11
|
+
* no local version file to compare, so update is always a fresh pull
|
|
12
|
+
* (equivalent to `--force`; cheap and reliable). See spec §9.
|
|
13
|
+
*/
|
|
14
|
+
export declare function updatePluginByName(name: string, installedAt: string, force: boolean): Promise<UpdateResult>;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { detectPluginFormat } from "./detectFormat.js";
|
|
4
|
+
import { pluginInstallDir } from "./paths.js";
|
|
5
|
+
import { uninstallPluginByName } from "./uninstall.js";
|
|
6
|
+
import { installPluginFromPath } from "./install.js";
|
|
7
|
+
import { installPluginFromSource } from "./installFromSource.js";
|
|
8
|
+
import { parseSource } from "./parseSource.js";
|
|
9
|
+
import { CodexPluginManifest, CSMeta, PluginInstallError } from "./types.js";
|
|
10
|
+
/**
|
|
11
|
+
* Reinstall a plugin from its recorded source.
|
|
12
|
+
*
|
|
13
|
+
* - Local source: reinstall when the source version changed, or when `force`.
|
|
14
|
+
* CC plugins have no version → only `force` updates them.
|
|
15
|
+
* - Remote (git) source: re-clone and reinstall every time — git sources carry
|
|
16
|
+
* no local version file to compare, so update is always a fresh pull
|
|
17
|
+
* (equivalent to `--force`; cheap and reliable). See spec §9.
|
|
18
|
+
*/
|
|
19
|
+
export async function updatePluginByName(name, installedAt, force) {
|
|
20
|
+
const dir = pluginInstallDir(name);
|
|
21
|
+
const metaPath = join(dir, ".cs-meta.json");
|
|
22
|
+
if (!existsSync(metaPath))
|
|
23
|
+
throw new PluginInstallError(`no plugin named '${name}'`);
|
|
24
|
+
const meta = CSMeta.parse(JSON.parse(readFileSync(metaPath, "utf-8")));
|
|
25
|
+
const parsed = parseSource(meta.source);
|
|
26
|
+
if (parsed.kind === "remote") {
|
|
27
|
+
// No local version to diff against — always re-clone and reinstall.
|
|
28
|
+
// uninstall-then-install isn't atomic: if the reinstall fails (clone
|
|
29
|
+
// error, bad plugin) the old copy is already gone. We can't roll back the
|
|
30
|
+
// removal, but we surface a clear error instead of leaving silent
|
|
31
|
+
// inconsistency.
|
|
32
|
+
uninstallPluginByName(name);
|
|
33
|
+
try {
|
|
34
|
+
await installPluginFromSource(parsed, name, installedAt);
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
throw new PluginInstallError(`update failed and '${name}' was removed during reinstall: ` +
|
|
38
|
+
`${err instanceof Error ? err.message : String(err)}. Reinstall it from ${meta.source}.`);
|
|
39
|
+
}
|
|
40
|
+
return { updated: true, reason: "reinstalled from git source" };
|
|
41
|
+
}
|
|
42
|
+
if (!existsSync(meta.source)) {
|
|
43
|
+
throw new PluginInstallError(`source no longer exists: ${meta.source}`);
|
|
44
|
+
}
|
|
45
|
+
if (!force) {
|
|
46
|
+
if (detectPluginFormat(meta.source) === "codex") {
|
|
47
|
+
const manifest = CodexPluginManifest.parse(JSON.parse(readFileSync(join(meta.source, ".codex-plugin", "plugin.json"), "utf-8")));
|
|
48
|
+
if (manifest.version === meta.version) {
|
|
49
|
+
return { updated: false, reason: "already up to date" };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
return { updated: false, reason: "CC plugin needs --force to reinstall" };
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
uninstallPluginByName(name);
|
|
57
|
+
try {
|
|
58
|
+
await installPluginFromPath(meta.source, name, installedAt);
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
throw new PluginInstallError(`update failed and '${name}' was removed during reinstall: ` +
|
|
62
|
+
`${err instanceof Error ? err.message : String(err)}. Reinstall it from ${meta.source}.`);
|
|
63
|
+
}
|
|
64
|
+
return { updated: true, reason: "reinstalled" };
|
|
65
|
+
}
|
|
@@ -48,5 +48,12 @@ import type { HookRegistry } from "../hooks/registry.js";
|
|
|
48
48
|
* multiple times — the caller is responsible for not double-registering
|
|
49
49
|
* (HookRegistry has no de-dup; the engine constructor calls this exactly
|
|
50
50
|
* once after creating the registry).
|
|
51
|
+
*
|
|
52
|
+
* `disabledPlugins` is the coarse "plugin total switch" — bare plugin names
|
|
53
|
+
* (no `@marketplace`, no `:` suffix), matching scanSkills' semantics. A
|
|
54
|
+
* disabled plugin contributes NO hooks, so e.g. disabling "superpowers"
|
|
55
|
+
* also suppresses its SessionStart injection — not just its Skill-tool
|
|
56
|
+
* entries. Without this, `disabledPlugins` only filtered the skill list and
|
|
57
|
+
* the plugin's hooks still fired regardless.
|
|
51
58
|
*/
|
|
52
|
-
export declare function loadPluginHooks(registry: HookRegistry): void;
|
|
59
|
+
export declare function loadPluginHooks(registry: HookRegistry, disabledPlugins?: string[]): void;
|
|
@@ -114,10 +114,20 @@ function pluginNameFromKey(key) {
|
|
|
114
114
|
* multiple times — the caller is responsible for not double-registering
|
|
115
115
|
* (HookRegistry has no de-dup; the engine constructor calls this exactly
|
|
116
116
|
* once after creating the registry).
|
|
117
|
+
*
|
|
118
|
+
* `disabledPlugins` is the coarse "plugin total switch" — bare plugin names
|
|
119
|
+
* (no `@marketplace`, no `:` suffix), matching scanSkills' semantics. A
|
|
120
|
+
* disabled plugin contributes NO hooks, so e.g. disabling "superpowers"
|
|
121
|
+
* also suppresses its SessionStart injection — not just its Skill-tool
|
|
122
|
+
* entries. Without this, `disabledPlugins` only filtered the skill list and
|
|
123
|
+
* the plugin's hooks still fired regardless.
|
|
117
124
|
*/
|
|
118
|
-
export function loadPluginHooks(registry) {
|
|
125
|
+
export function loadPluginHooks(registry, disabledPlugins = []) {
|
|
119
126
|
const data = readInstalledPlugins();
|
|
127
|
+
const disabledSet = new Set(disabledPlugins);
|
|
120
128
|
for (const [key, entries] of Object.entries(data.plugins)) {
|
|
129
|
+
if (disabledSet.has(pluginNameFromKey(key)))
|
|
130
|
+
continue;
|
|
121
131
|
for (const entry of entries) {
|
|
122
132
|
const installPath = entry.installPath;
|
|
123
133
|
if (!installPath || !existsSync(installPath))
|
|
@@ -5,9 +5,15 @@
|
|
|
5
5
|
* at the MVP subset (github + git sources only, no auto-update,
|
|
6
6
|
* no policy blocking, no GCS mirror).
|
|
7
7
|
*/
|
|
8
|
-
import type { MarketplaceSource, PluginMarketplace } from "./types.js";
|
|
8
|
+
import type { MarketplaceFormat, MarketplaceSource, PluginMarketplace } from "./types.js";
|
|
9
|
+
export type { MarketplaceFormat } from "./types.js";
|
|
9
10
|
export declare function marketplacesRoot(): string;
|
|
10
11
|
export declare function marketplaceDir(name: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* Classify a cloned marketplace by which manifest files it ships:
|
|
14
|
+
* both → universal, only .agents/plugins → codex, otherwise claude-code.
|
|
15
|
+
*/
|
|
16
|
+
export declare function detectMarketplaceFormat(dir: string): MarketplaceFormat;
|
|
11
17
|
export type AddMarketplaceResult = {
|
|
12
18
|
ok: true;
|
|
13
19
|
name: string;
|
|
@@ -40,6 +46,7 @@ export interface ListedMarketplace {
|
|
|
40
46
|
installLocation: string;
|
|
41
47
|
lastUpdated: string;
|
|
42
48
|
pluginCount: number;
|
|
49
|
+
format: MarketplaceFormat;
|
|
43
50
|
}
|
|
44
51
|
/**
|
|
45
52
|
* Lists all known marketplaces with a quick plugin count read from each
|
|
@@ -20,8 +20,39 @@ export function marketplacesRoot() {
|
|
|
20
20
|
export function marketplaceDir(name) {
|
|
21
21
|
return join(marketplacesRoot(), name);
|
|
22
22
|
}
|
|
23
|
+
const CC_MANIFEST_REL = [".claude-plugin", "marketplace.json"];
|
|
24
|
+
const CODEX_MANIFEST_REL = [".agents", "plugins", "marketplace.json"];
|
|
25
|
+
/**
|
|
26
|
+
* Resolve the marketplace manifest inside a cloned repo. Claude Code's format
|
|
27
|
+
* lives at .claude-plugin/marketplace.json; the Codex / agents format lives at
|
|
28
|
+
* .agents/plugins/marketplace.json. Prefer the CC manifest when present (it is
|
|
29
|
+
* our canonical shape), else fall back to the Codex one. Returns null when
|
|
30
|
+
* neither exists.
|
|
31
|
+
*/
|
|
32
|
+
function resolveManifestPath(dir) {
|
|
33
|
+
const cc = join(dir, ...CC_MANIFEST_REL);
|
|
34
|
+
if (existsSync(cc))
|
|
35
|
+
return cc;
|
|
36
|
+
const codex = join(dir, ...CODEX_MANIFEST_REL);
|
|
37
|
+
if (existsSync(codex))
|
|
38
|
+
return codex;
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
23
41
|
function marketplaceJsonPath(name) {
|
|
24
|
-
return
|
|
42
|
+
return resolveManifestPath(marketplaceDir(name));
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Classify a cloned marketplace by which manifest files it ships:
|
|
46
|
+
* both → universal, only .agents/plugins → codex, otherwise claude-code.
|
|
47
|
+
*/
|
|
48
|
+
export function detectMarketplaceFormat(dir) {
|
|
49
|
+
const hasCc = existsSync(join(dir, ...CC_MANIFEST_REL));
|
|
50
|
+
const hasCodex = existsSync(join(dir, ...CODEX_MANIFEST_REL));
|
|
51
|
+
if (hasCc && hasCodex)
|
|
52
|
+
return "universal";
|
|
53
|
+
if (hasCodex)
|
|
54
|
+
return "codex";
|
|
55
|
+
return "claude-code";
|
|
25
56
|
}
|
|
26
57
|
function sourceToCloneUrl(source) {
|
|
27
58
|
return source.source === "github" ? githubRepoToCloneUrl(source.repo) : source.url;
|
|
@@ -55,11 +86,11 @@ export async function addMarketplace(name, source) {
|
|
|
55
86
|
}
|
|
56
87
|
}
|
|
57
88
|
const manifestPath = marketplaceJsonPath(name);
|
|
58
|
-
if (!
|
|
89
|
+
if (!manifestPath) {
|
|
59
90
|
rmSync(dir, { recursive: true, force: true });
|
|
60
91
|
return {
|
|
61
92
|
ok: false,
|
|
62
|
-
error: `Marketplace ${name}:
|
|
93
|
+
error: `Marketplace ${name}: no marketplace.json found (looked in .claude-plugin/ and .agents/plugins/).`,
|
|
63
94
|
};
|
|
64
95
|
}
|
|
65
96
|
let raw;
|
|
@@ -82,6 +113,7 @@ export async function addMarketplace(name, source) {
|
|
|
82
113
|
source,
|
|
83
114
|
installLocation: dir,
|
|
84
115
|
lastUpdated: new Date().toISOString(),
|
|
116
|
+
format: detectMarketplaceFormat(dir),
|
|
85
117
|
};
|
|
86
118
|
upsertKnownMarketplace(name, entry);
|
|
87
119
|
return { ok: true, name, marketplace: v.value, replaced: Boolean(existing) };
|
|
@@ -108,7 +140,7 @@ export function loadMarketplace(name) {
|
|
|
108
140
|
if (!known[name])
|
|
109
141
|
return null;
|
|
110
142
|
const manifestPath = marketplaceJsonPath(name);
|
|
111
|
-
if (!
|
|
143
|
+
if (!manifestPath)
|
|
112
144
|
return null;
|
|
113
145
|
let raw;
|
|
114
146
|
try {
|
|
@@ -136,6 +168,8 @@ export function listMarketplaces() {
|
|
|
136
168
|
installLocation: entry.installLocation,
|
|
137
169
|
lastUpdated: entry.lastUpdated,
|
|
138
170
|
pluginCount: mp ? mp.plugins.length : -1,
|
|
171
|
+
// Re-detect from disk when the stored entry predates the format field.
|
|
172
|
+
format: entry.format ?? detectMarketplaceFormat(entry.installLocation),
|
|
139
173
|
});
|
|
140
174
|
}
|
|
141
175
|
return out.sort((a, b) => a.name.localeCompare(b.name));
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
* branch — not the CC one.
|
|
32
32
|
*/
|
|
33
33
|
import { spawn } from "node:child_process";
|
|
34
|
+
import { MAX_HOOK_OUTPUT_BYTES } from "../hooks/hook-output.js";
|
|
34
35
|
const DEFAULT_TIMEOUT_MS = 60_000;
|
|
35
36
|
/**
|
|
36
37
|
* Extract the user-facing context string from a CC plugin's stdout JSON.
|
|
@@ -99,6 +100,13 @@ export async function runPluginCommandHook(spec, ctx) {
|
|
|
99
100
|
let stdout = "";
|
|
100
101
|
let stderr = "";
|
|
101
102
|
let settled = false;
|
|
103
|
+
// Output byte caps mirror src/hooks/shell-runner.ts so a chatty plugin
|
|
104
|
+
// hook can't hold engine memory hostage. Past the cap we SIGTERM the
|
|
105
|
+
// child and treat the hook as failed; stderr cap truncates with a
|
|
106
|
+
// marker instead of failing the hook.
|
|
107
|
+
let stdoutBytes = 0;
|
|
108
|
+
let stdoutCapped = false;
|
|
109
|
+
let stderrCapped = false;
|
|
102
110
|
const settle = (value) => {
|
|
103
111
|
if (settled)
|
|
104
112
|
return;
|
|
@@ -125,9 +133,29 @@ export async function runPluginCommandHook(spec, ctx) {
|
|
|
125
133
|
settle({});
|
|
126
134
|
}, timeoutMs);
|
|
127
135
|
child.stdout?.on("data", (chunk) => {
|
|
136
|
+
stdoutBytes += chunk.length;
|
|
137
|
+
if (stdoutBytes > MAX_HOOK_OUTPUT_BYTES) {
|
|
138
|
+
if (!stdoutCapped) {
|
|
139
|
+
stdoutCapped = true;
|
|
140
|
+
// eslint-disable-next-line no-console
|
|
141
|
+
console.warn(`[plugin-hook] ${spec.pluginKey} ${ctx.eventName} stdout exceeded ${MAX_HOOK_OUTPUT_BYTES} bytes — killing`);
|
|
142
|
+
try {
|
|
143
|
+
child.kill("SIGTERM");
|
|
144
|
+
}
|
|
145
|
+
catch { /* already exited */ }
|
|
146
|
+
}
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
128
149
|
stdout += chunk.toString("utf8");
|
|
129
150
|
});
|
|
130
151
|
child.stderr?.on("data", (chunk) => {
|
|
152
|
+
if (stderr.length + chunk.length > MAX_HOOK_OUTPUT_BYTES) {
|
|
153
|
+
if (!stderrCapped) {
|
|
154
|
+
stderrCapped = true;
|
|
155
|
+
stderr += "\n…[stderr truncated]";
|
|
156
|
+
}
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
131
159
|
stderr += chunk.toString("utf8");
|
|
132
160
|
});
|
|
133
161
|
child.on("error", (err) => {
|
|
@@ -138,6 +166,12 @@ export async function runPluginCommandHook(spec, ctx) {
|
|
|
138
166
|
});
|
|
139
167
|
child.on("close", (code) => {
|
|
140
168
|
clearTimeout(timer);
|
|
169
|
+
if (stdoutCapped) {
|
|
170
|
+
// eslint-disable-next-line no-console
|
|
171
|
+
console.error(`[plugin-hook] ${spec.pluginKey} ${ctx.eventName} killed due to oversized stdout (> ${MAX_HOOK_OUTPUT_BYTES} bytes)`);
|
|
172
|
+
settle({});
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
141
175
|
if (code !== 0) {
|
|
142
176
|
// eslint-disable-next-line no-console
|
|
143
177
|
console.warn(`[plugin-hook] ${spec.pluginKey} ${ctx.eventName} exited ${code}; stderr:`, stderr.slice(0, 500));
|
|
@@ -5,6 +5,17 @@
|
|
|
5
5
|
* sparse-checkout, no npm/pip.
|
|
6
6
|
*/
|
|
7
7
|
import type { PluginInstallEntry } from "./types.js";
|
|
8
|
+
/**
|
|
9
|
+
* Resolve a candidate `installPath` to a realpath and verify it lives strictly
|
|
10
|
+
* underneath the plugin cache root. Returns the resolved path on success, or
|
|
11
|
+
* null when the path is missing, escapes the cache, equals the cache root
|
|
12
|
+
* itself, or is otherwise unsafe to remove.
|
|
13
|
+
*
|
|
14
|
+
* Exported so tests can exercise the safety predicate directly without
|
|
15
|
+
* arranging a full uninstall — the contract this defends (no rmSync outside
|
|
16
|
+
* the plugin cache) is the entire point of T2 / Workstream A2.
|
|
17
|
+
*/
|
|
18
|
+
export declare function resolveSafePluginPath(installPath: string, cacheRoot: string): string | null;
|
|
8
19
|
export interface VarRewriteReport {
|
|
9
20
|
filesScanned: number;
|
|
10
21
|
filesRewritten: number;
|
|
@@ -18,6 +29,16 @@ export type InstallResult = {
|
|
|
18
29
|
ok: false;
|
|
19
30
|
error: string;
|
|
20
31
|
};
|
|
32
|
+
/**
|
|
33
|
+
* Compare a marketplace-declared SHA against the cloned HEAD. The
|
|
34
|
+
* declaration is allowed to be a short prefix (>= 7 chars, standard git
|
|
35
|
+
* abbreviation length); for stricter integrity guarantees marketplaces
|
|
36
|
+
* should pin the full 40-char hash. Case-insensitive.
|
|
37
|
+
*
|
|
38
|
+
* Exported so a unit test can pin the policy without spinning up a real
|
|
39
|
+
* clone.
|
|
40
|
+
*/
|
|
41
|
+
export declare function shaMatches(declared: string, actual: string): boolean;
|
|
21
42
|
/**
|
|
22
43
|
* Install a plugin from a previously-added marketplace into the user
|
|
23
44
|
* cache. Idempotent within a process: re-installing replaces the
|