opencode-ultra 0.7.0 → 0.7.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.
@@ -7,4 +7,14 @@ export declare function extractPromptText(parts: Array<{
7
7
  type: string;
8
8
  text?: string;
9
9
  }>): string;
10
- export declare function detectKeywords(text: string): DetectedKeyword[];
10
+ /** Context for generating dynamic evolve message */
11
+ export interface EvolveContext {
12
+ agents: Record<string, {
13
+ model: string;
14
+ description: string;
15
+ }>;
16
+ tools: string[];
17
+ hooks: string[];
18
+ features: string[];
19
+ }
20
+ export declare function detectKeywords(text: string, evolveCtx?: EvolveContext): DetectedKeyword[];
package/dist/index.js CHANGED
@@ -29070,6 +29070,30 @@ var OpenCodeUltra = async (ctx) => {
29070
29070
  const astGrepBin = findAstGrepBinary();
29071
29071
  const astSearch = astGrepBin ? createAstSearchTool(ctx, astGrepBin) : null;
29072
29072
  const evolveApply = createEvolveApplyTool(ctx);
29073
+ const buildEvolveCtx = (toolNames) => ({
29074
+ agents: Object.fromEntries(Object.entries(agents).map(([name, def]) => [name, { model: def.model, description: def.description }])),
29075
+ tools: toolNames,
29076
+ hooks: [
29077
+ ...!disabledHooks.has("keyword-detector") ? ["keyword-detector (ultrawork/search/analyze/think/evolve detection)"] : [],
29078
+ ...!disabledHooks.has("rules-injector") ? ["rules-injector (architecture.md/codestyle.md/rules.md injection)"] : [],
29079
+ ...!disabledHooks.has("fragment-injector") ? ["fragment-injector (conditional context fragments)"] : [],
29080
+ ...!disabledHooks.has("prompt-renderer") ? ["prompt-renderer (template-based prompt rendering)"] : [],
29081
+ ...!disabledHooks.has("todo-enforcer") ? ["todo-enforcer (force completion of unfinished TODOs)"] : [],
29082
+ ...!disabledHooks.has("comment-checker") ? ["comment-checker (detect AI slop comments in code)"] : [],
29083
+ ...!disabledHooks.has("token-truncation") ? ["token-truncation (auto-truncate large tool outputs)"] : [],
29084
+ ...!disabledHooks.has("session-compaction") ? ["session-compaction (auto-compact long sessions)"] : []
29085
+ ],
29086
+ features: [
29087
+ pool ? "concurrency control (semaphore-based per-provider/model limits)" : "no concurrency limits",
29088
+ "prompt injection sanitizer (17 patterns, 6 categories)",
29089
+ "trust score system (5-factor npm package evaluation)",
29090
+ "spawn limit (max concurrent sub-agents)",
29091
+ "agent timeout (per-agent execution timeout)",
29092
+ pluginConfig.categories ? "categories (model/variant routing per task type)" : "no categories configured",
29093
+ "continuity ledger (persistent key-value store across sessions)",
29094
+ "multi-language keyword detection (EN/JP/CN)"
29095
+ ]
29096
+ });
29073
29097
  const todoEnforcer = createTodoEnforcer(ctx, internalSessions, pluginConfig.todo_enforcer?.maxEnforcements);
29074
29098
  const commentCheckerHook = createCommentCheckerHook(internalSessions, pluginConfig.comment_checker?.maxRatio, pluginConfig.comment_checker?.slopThreshold);
29075
29099
  const tokenTruncationHook = createTokenTruncationHook(internalSessions, pluginConfig.token_truncation?.maxChars);
@@ -29152,30 +29176,7 @@ var OpenCodeUltra = async (ctx) => {
29152
29176
  }
29153
29177
  if (!disabledHooks.has("keyword-detector")) {
29154
29178
  const promptText = extractPromptText(output.parts);
29155
- const evolveCtx = {
29156
- agents: Object.fromEntries(Object.entries(agents).map(([name, def]) => [name, { model: def.model, description: def.description }])),
29157
- tools: Object.keys(toolRegistry),
29158
- hooks: [
29159
- ...!disabledHooks.has("keyword-detector") ? ["keyword-detector (ultrawork/search/analyze/think/evolve detection)"] : [],
29160
- ...!disabledHooks.has("rules-injector") ? ["rules-injector (architecture.md/codestyle.md/rules.md injection)"] : [],
29161
- ...!disabledHooks.has("fragment-injector") ? ["fragment-injector (conditional context fragments)"] : [],
29162
- ...!disabledHooks.has("prompt-renderer") ? ["prompt-renderer (template-based prompt rendering)"] : [],
29163
- ...!disabledHooks.has("todo-enforcer") ? ["todo-enforcer (force completion of unfinished TODOs)"] : [],
29164
- ...!disabledHooks.has("comment-checker") ? ["comment-checker (detect AI slop comments in code)"] : [],
29165
- ...!disabledHooks.has("token-truncation") ? ["token-truncation (auto-truncate large tool outputs)"] : [],
29166
- ...!disabledHooks.has("session-compaction") ? ["session-compaction (auto-compact long sessions)"] : []
29167
- ],
29168
- features: [
29169
- pool ? "concurrency control (semaphore-based per-provider/model limits)" : "no concurrency limits",
29170
- "prompt injection sanitizer (17 patterns, 6 categories)",
29171
- "trust score system (5-factor npm package evaluation)",
29172
- "spawn limit (max concurrent sub-agents)",
29173
- "agent timeout (per-agent execution timeout)",
29174
- pluginConfig.categories ? "categories (model/variant routing per task type)" : "no categories configured",
29175
- "continuity ledger (persistent key-value store across sessions)",
29176
- "multi-language keyword detection (EN/JP/CN)"
29177
- ]
29178
- };
29179
+ const evolveCtx = buildEvolveCtx(Object.keys(toolRegistry));
29179
29180
  const detected = detectKeywords(promptText, evolveCtx);
29180
29181
  if (detected.length > 0) {
29181
29182
  const hasUltrawork = detected.some((k) => k.type === "ultrawork");
@@ -1,2 +1,2 @@
1
1
  export { sanitizeAgentOutput, sanitizeSpawnResult, type SanitizeResult } from "./sanitizer";
2
- export { computeTrustScore, isTyposquatSuspect, formatTrustTable, type PackageMetadata, type TrustScoreResult, type TrustFactor, } from "./trust-score";
2
+ export { computeTrustScore, isTyposquatSuspect, isHighPrivilege, formatTrustTable, MAX_TRUST_SCORE, type PackageMetadata, type TrustScoreResult, type TrustFactor, } from "./trust-score";
@@ -2,17 +2,21 @@
2
2
  * Trust Score — evaluates npm packages for reliability and safety.
3
3
  * Used by evolve mode to rank plugin recommendations.
4
4
  *
5
- * Score 0–100:
6
- * 90–100 HIGH trust (well-maintained, popular, verified)
7
- * 70–89 MEDIUM trust (decent maintenance, some usage)
8
- * 40–69 LOW trust (stale, low usage, or missing metadata)
9
- * 0–39 RISKY (abandoned, typosquat suspect, no repo)
5
+ * Factors (max 108):
6
+ * recency (25), popularity (25), quality (20), repository (15),
7
+ * safety (15), provenance (8), dependency_risk (0 or -5 penalty)
8
+ *
9
+ * Levels (by percentage of 108):
10
+ * 90%+ HIGH | 70-89% MEDIUM | 40-69% LOW | <40% RISKY
10
11
  */
12
+ export declare const MAX_TRUST_SCORE = 108;
11
13
  export interface PackageMetadata {
12
14
  name: string;
13
15
  version?: string;
14
16
  description?: string;
15
17
  license?: string;
18
+ /** Whether npm provenance/attestation is available */
19
+ hasProvenance?: boolean;
16
20
  /** ISO date string of last publish */
17
21
  lastPublished?: string;
18
22
  /** Weekly npm downloads */
@@ -42,6 +46,8 @@ export interface TrustFactor {
42
46
  }
43
47
  export declare function computeTrustScore(meta: PackageMetadata): TrustScoreResult;
44
48
  export declare function isTyposquatSuspect(name: string): boolean;
49
+ /** Check if package name suggests high-privilege access (PTY, exec, shell, sudo) */
50
+ export declare function isHighPrivilege(name: string): boolean;
45
51
  /**
46
52
  * Format trust scores as a markdown table for evolve output.
47
53
  */
@@ -0,0 +1,40 @@
1
+ /**
2
+ * evolve-filter — Pure scoring and filtering logic for evolve proposals.
3
+ *
4
+ * No side effects. All functions are deterministic.
5
+ */
6
+ export interface EvolveProposal {
7
+ title: string;
8
+ priority: "P0" | "P1" | "P2";
9
+ effort: "Low" | "Medium" | "High";
10
+ description: string;
11
+ files?: string[];
12
+ currentState?: string;
13
+ inspiration?: string;
14
+ }
15
+ export interface FilteredProposal extends EvolveProposal {
16
+ score: number;
17
+ accepted: boolean;
18
+ reason?: string;
19
+ }
20
+ export interface FilterConfig {
21
+ minScore?: number;
22
+ maxProposals?: number;
23
+ }
24
+ export declare function scoreProposal(p: EvolveProposal): number;
25
+ export declare function filterProposals(proposals: EvolveProposal[], config?: FilterConfig): FilteredProposal[];
26
+ /**
27
+ * Parse Sisyphus evolve output into structured proposals.
28
+ *
29
+ * Expected format (from keyword-detector EVOLVE_MESSAGE Phase 3):
30
+ * ```
31
+ * ## Improvement: [Feature Name]
32
+ * **Inspiration**: [Plugin name] — [what it does]
33
+ * **Current state**: [what opencode-ultra has now]
34
+ * **Why**: [concrete benefit]
35
+ * **How**: [which file to modify, what to add]
36
+ * **Effort**: Low / Medium / High
37
+ * **Priority**: P0 / P1 / P2
38
+ * ```
39
+ */
40
+ export declare function parseProposalsFromMarkdown(markdown: string): EvolveProposal[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-ultra",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "description": "Lightweight OpenCode 1.2.x plugin — ultrawork mode, multi-agent orchestration, rules injection",
5
5
  "keywords": [
6
6
  "opencode",