oh-my-opencode-lite 0.1.1 → 0.1.3

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 CHANGED
@@ -7,7 +7,7 @@
7
7
  ---
8
8
 
9
9
  Delegate-first OpenCode plugin with a seven-agent roster, root-session
10
- `thoth_mem` persistence, disk-backed delegation records, bundled brainstorming,
10
+ `thoth_mem` persistence, disk-backed delegation records, bundled requirements-interview,
11
11
  and a full SDD workflow.
12
12
 
13
13
  oh-my-opencode-lite keeps the `orchestrator` lean, pushes discovery into
@@ -43,7 +43,7 @@ bunx oh-my-opencode-lite@latest install --reset
43
43
  ```
44
44
 
45
45
  When skills are enabled, the installer adds the recommended external skills and
46
- copies the bundled brainstorming, cartography, plan-reviewer,
46
+ copies the bundled requirements-interview, cartography, plan-reviewer,
47
47
  executing-plans, and SDD skills into your OpenCode skills directory.
48
48
 
49
49
  ### For LLM agents
@@ -83,6 +83,11 @@ specialists execute. Read-only discovery work goes to async specialists for
83
83
  context isolation. Advisory and write-capable work stays sync so review, undo
84
84
  safety, and verification remain straightforward.
85
85
 
86
+ For blocking user decisions, the `orchestrator` uses a `question` tool —
87
+ agents do not ask those questions in plain text. Independent work can be
88
+ launched together when parallel dispatch is safe, and failed delegations are
89
+ retried once before being reported back to the user.
90
+
86
91
  ### 🔑 Primary Agent
87
92
 
88
93
  <table width="100%">
@@ -227,7 +232,7 @@ safety, and verification remain straightforward.
227
232
  - Disk-persisted delegation results that survive compaction and in-memory loss
228
233
  - Bundled SDD pipeline: `sdd-propose`, `sdd-spec`, `sdd-design`, `sdd-tasks`,
229
234
  `sdd-apply`, `sdd-verify`, `sdd-archive`
230
- - Brainstorming skill with clarification-gate hook for ambiguous work
235
+ - Requirements-interview skill for clarifying ambiguous work before implementation
231
236
  - `plan-reviewer` for oracle review loops on task plans
232
237
  - `executing-plans` for task-state ownership and progress tracking
233
238
  - `cartography` for repository mapping and codemap generation
@@ -249,16 +254,17 @@ The bundled SDD workflow follows this path:
249
254
  propose -> [spec || design] -> tasks -> apply -> verify -> archive
250
255
  ```
251
256
 
252
- For medium work, brainstorming can route into an accelerated path that starts at
257
+ For medium work, the requirements interview can route into an accelerated path that starts at
253
258
  `propose -> tasks`. For complex work, the full path is used.
254
259
 
255
- Artifacts can be persisted in three modes:
260
+ Artifacts can be persisted in four modes:
256
261
 
257
- | Mode | Writes to | Use when |
258
- | --- | --- | --- |
259
- | `thoth-mem` | Memory only | Fast iteration without repo planning files |
260
- | `openspec` | `openspec/` files only | Reviewable planning artifacts in the repo |
261
- | `hybrid` | Both | Maximum durability; default |
262
+ | Mode | Writes to | Cost | Use when |
263
+ | --- | --- | --- | --- |
264
+ | `thoth-mem` | Memory only | Low | Fast iteration without repo planning files |
265
+ | `openspec` | `openspec/` files only | Medium | Reviewable planning artifacts in the repo |
266
+ | `hybrid` | Both | High | Maximum durability; default |
267
+ | `none` | Neither | Lowest | Ephemeral iterations, no persistence |
262
268
 
263
269
  After `sdd-tasks`, the orchestrator can run an oracle review loop with
264
270
  `plan-reviewer`:
@@ -269,17 +275,22 @@ After `sdd-tasks`, the orchestrator can run an oracle review loop with
269
275
  4. Repeat until `[OKAY]`
270
276
  5. Continue into execution
271
277
 
272
- During execution, `executing-plans` owns task-state tracking:
278
+ During execution, `executing-plans` owns task-state tracking. Progress has two
279
+ mandatory layers: `todowrite` for the visual task list, plus a persistent SDD
280
+ artifact via `tasks.md` checkboxes and/or `thoth_mem`.
273
281
 
274
282
  - `- [ ]` pending
275
283
  - `- [~]` in progress
276
284
  - `- [x]` completed
277
285
  - `- [-]` skipped with reason
278
286
 
279
- ## Brainstorming & Clarification Gate
287
+ ## Requirements Interview
280
288
 
281
- The bundled `brainstorming` skill is the front door for ambiguous or substantial
282
- work. Its workflow is six phases:
289
+ The bundled `requirements-interview` skill is the front door for ambiguous or substantial
290
+ work. It is step-0 in the orchestrator prompt and runs before implementation when the
291
+ request is open-ended, spans multiple parts of the system, or needs scope calibration.
292
+
293
+ Its workflow is six phases:
283
294
 
284
295
  1. Context gathering
285
296
  2. Interview
@@ -288,13 +299,8 @@ work. Its workflow is six phases:
288
299
  5. User approval
289
300
  6. Handoff
290
301
 
291
- The clarification-gate hook can auto-detect requests that should go through this
292
- flow before implementation. It checks for explicit planning keywords plus scope
293
- signals such as multi-view work, API/data changes, restructuring, multi-layer
294
- impact, business-language requests, open-ended phrasing, and cross-directory
295
- scope. When triggered, it injects a reminder for the `orchestrator` to load the
296
- brainstorming skill, ask one clarifying question at a time, and wait for
297
- explicit approval before coding.
302
+ After clarification, the skill routes the work into direct implementation, accelerated
303
+ SDD, or full SDD based on complexity assessment.
298
304
 
299
305
  ## 🧩 Skills & MCP Servers
300
306
 
@@ -302,9 +308,10 @@ explicit approval before coding.
302
308
 
303
309
  | Skill | Category | Purpose |
304
310
  | --- | --- | --- |
305
- | `brainstorming` | Clarification | Clarify intent, assess scope, and choose direct work vs accelerated or full SDD |
311
+ | `requirements-interview` | Clarification | Clarify intent, assess scope, and choose direct work vs accelerated or full SDD |
306
312
  | `cartography` | Discovery | Generate and update hierarchical repository codemaps |
307
313
  | `plan-reviewer` | Review | Validate `tasks.md` for real execution blockers and return `[OKAY]` or `[REJECT]` |
314
+ | `sdd-init` | SDD | Bootstrap OpenSpec structure and SDD context for a project |
308
315
  | `sdd-propose` | SDD | Create or update `proposal.md` |
309
316
  | `sdd-spec` | SDD | Write OpenSpec delta specs with RFC 2119 requirements and scenarios |
310
317
  | `sdd-design` | SDD | Produce `design.md` with technical decisions and file changes |
@@ -332,6 +339,23 @@ explicit approval before coding.
332
339
  | `grep_app` | Public GitHub code search | No auth required |
333
340
  | `thoth_mem` | Local persistent memory and artifact storage | Local command, default `npx -y thoth-mem@latest` |
334
341
 
342
+ > **🧠 [Thoth-Mem](https://github.com/EremesNG/thoth-mem)** is a persistent
343
+ > memory MCP server purpose-built for cross-session context. The orchestrator
344
+ > uses it to save architectural decisions, bug-fix learnings, SDD artifacts,
345
+ > and session summaries so the next session picks up where the last one left
346
+ > off — even after context-window compaction. It is included by default and
347
+ > runs locally via `npx`.
348
+
349
+ For targeted retrieval, Thoth-Mem uses a 3-layer recall protocol:
350
+
351
+ 1. `mem_search` — scan the compact index of IDs and titles
352
+ 2. `mem_timeline` — inspect chronological context around candidates
353
+ 3. `mem_get_observation` — read full content for selected records
354
+
355
+ After task completion, an automatic save nudge reminds the orchestrator to
356
+ persist important observations. Session start also degrades gracefully if
357
+ `thoth_mem` is unavailable, so memory errors do not block the main plugin flow.
358
+
335
359
  Skill and MCP access in this project is prompt-driven. The generated plugin
336
360
  config focuses on model presets and runtime options rather than per-agent
337
361
  permission matrices.
@@ -349,6 +373,8 @@ permission matrices.
349
373
 
350
374
  ## Development
351
375
 
376
+ The project targets `@opencode-ai/plugin` and `@opencode-ai/sdk` v1.3.3.
377
+
352
378
  | Command | Purpose |
353
379
  | --- | --- |
354
380
  | `bun run build` | Build TypeScript into `dist/` |
@@ -4,6 +4,9 @@ interface ComposeAgentPromptOptions {
4
4
  customAppendPrompt?: string;
5
5
  placeholders?: Record<string, string | number | undefined>;
6
6
  }
7
+ export declare const QUESTION_PROTOCOL = "<questions>\nUse the `question` tool for blocking decisions. NEVER ask in plain text.\nPut the recommended option first with \"(Recommended)\". Short headers (<=30 chars).\nAfter calling question, STOP \u2014 do not continue execution.\n</questions>";
8
+ export declare const SUBAGENT_RULES = "- Do not call thoth-mem session or prompt tools \u2014 memory is orchestrator-owned.\n- Use `question` tool for blocking decisions, never plain text.";
9
+ export declare const RESPONSE_BUDGET = "Your response returns to an expensive orchestrator model. Be ruthlessly concise:\n- Return insights and conclusions, NEVER raw file contents or full code blocks.\n- Structured results (status, summary, files, issues) over prose.\n- If the orchestrator needs more detail, it will ask in a follow-up.";
7
10
  export declare function appendPromptSections(...sections: Array<string | undefined>): string;
8
11
  export declare function replacePromptPlaceholders(template: string, placeholders?: Record<string, string | number | undefined>): string;
9
12
  export declare function composeAgentPrompt({ basePrompt, customPrompt, customAppendPrompt, placeholders, }: ComposeAgentPromptOptions): string;
@@ -56,6 +56,7 @@ export declare class BackgroundTaskManager {
56
56
  private agentBySessionId;
57
57
  private client;
58
58
  private directory;
59
+ private worktreeDirectory;
59
60
  private tmuxEnabled;
60
61
  private config?;
61
62
  private backgroundConfig;
@@ -64,7 +65,7 @@ export declare class BackgroundTaskManager {
64
65
  private activeStarts;
65
66
  private maxConcurrentStarts;
66
67
  private completionResolvers;
67
- constructor(ctx: PluginInput, tmuxConfig?: TmuxConfig, config?: PluginConfig, delegationManager?: DelegationManager);
68
+ constructor(ctx: PluginInput, tmuxConfig?: TmuxConfig, config?: PluginConfig, delegationManager?: DelegationManager, worktreeDirectory?: string);
68
69
  private resolveRootSessionId;
69
70
  private createTaskId;
70
71
  private buildDelegationSummary;
@@ -114,15 +115,20 @@ export declare class BackgroundTaskManager {
114
115
  private processQueue;
115
116
  private resolveFallbackChain;
116
117
  private promptWithTimeout;
118
+ private createPatternPermission;
119
+ private createPatternRuleset;
117
120
  /**
118
- * Calculate tool permissions for a spawned agent based on its own delegation rules.
119
- * Agents that cannot delegate (leaf nodes) get delegation tools disabled entirely,
120
- * preventing models from even seeing tools they can never use.
121
+ * Calculate delegation permissions for a spawned agent based on its own
122
+ * delegation rules.
123
+ *
124
+ * The permission payload is the primary control for child sessions. Legacy
125
+ * `tools` flags remain as a backward-compatible fallback because the plugin
126
+ * client still exposes pre-v2 prompt typings.
121
127
  *
122
128
  * @param agentName - The agent type being spawned
123
- * @returns Tool permissions object with background_task and task enabled/disabled
129
+ * @returns Permission payload plus legacy tool toggles for compatibility
124
130
  */
125
- private calculateToolPermissions;
131
+ private calculateDelegationPermissions;
126
132
  /**
127
133
  * Start a task in the background (Phase B).
128
134
  */
package/dist/cli/index.js CHANGED
@@ -570,10 +570,10 @@ var SHARED_SKILL_DIRECTORY2 = "_shared";
570
570
  var SHARED_SKILL_SOURCE_PATH = `src/skills/${SHARED_SKILL_DIRECTORY2}`;
571
571
  var CUSTOM_SKILLS = [
572
572
  {
573
- name: "brainstorming",
574
- description: "Understand user intent and scope through structured clarification before implementation",
573
+ name: "requirements-interview",
574
+ description: "Mandatory step-0 discovery interview to understand user intent, clarify scope, and choose the right path before implementation",
575
575
  allowedAgents: ["orchestrator"],
576
- sourcePath: "src/skills/brainstorming"
576
+ sourcePath: "src/skills/requirements-interview"
577
577
  },
578
578
  {
579
579
  name: "cartography",
@@ -587,6 +587,12 @@ var CUSTOM_SKILLS = [
587
587
  allowedAgents: ["orchestrator", "oracle"],
588
588
  sourcePath: "src/skills/plan-reviewer"
589
589
  },
590
+ {
591
+ name: "sdd-init",
592
+ description: "Initialize OpenSpec structure and SDD project context",
593
+ allowedAgents: ["orchestrator"],
594
+ sourcePath: "src/skills/sdd-init"
595
+ },
590
596
  {
591
597
  name: "sdd-propose",
592
598
  description: "Create change proposals for OpenSpec workflows",
@@ -9,8 +9,8 @@ import { type PluginConfig } from './schema';
9
9
  *
10
10
  * JSONC format is preferred over JSON (allows comments and trailing commas).
11
11
  * Project config takes precedence over user config. Nested objects (agents,
12
- * tmux, background, fallback, thoth, delegation, clarificationGate,
13
- * artifactStore) are deep-merged, while top-level arrays are replaced entirely
12
+ * tmux, background, fallback, thoth, delegation, artifactStore) are
13
+ * deep-merged, while top-level arrays are replaced entirely
14
14
  * by project config.
15
15
  *
16
16
  * @param directory - Project directory to search for .opencode config
@@ -127,25 +127,6 @@ export declare const DelegationConfigSchema: z.ZodObject<{
127
127
  timeout: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
128
128
  }, z.core.$strip>;
129
129
  export type DelegationConfig = z.infer<typeof DelegationConfigSchema>;
130
- export declare const ClarificationGateModeSchema: z.ZodEnum<{
131
- off: "off";
132
- "explicit-only": "explicit-only";
133
- auto: "auto";
134
- "auto-for-planning": "auto-for-planning";
135
- }>;
136
- export declare const ClarificationGateConfigSchema: z.ZodObject<{
137
- mode: z.ZodDefault<z.ZodEnum<{
138
- off: "off";
139
- "explicit-only": "explicit-only";
140
- auto: "auto";
141
- "auto-for-planning": "auto-for-planning";
142
- }>>;
143
- min_scope_signals: z.ZodDefault<z.ZodNumber>;
144
- hard_complex_signal_threshold: z.ZodDefault<z.ZodNumber>;
145
- explicit_keywords: z.ZodOptional<z.ZodArray<z.ZodString>>;
146
- planning_keywords: z.ZodOptional<z.ZodArray<z.ZodString>>;
147
- }, z.core.$strip>;
148
- export type ClarificationGateConfig = z.infer<typeof ClarificationGateConfigSchema>;
149
130
  export declare const ArtifactStoreModeSchema: z.ZodEnum<{
150
131
  "thoth-mem": "thoth-mem";
151
132
  openspec: "openspec";
@@ -289,18 +270,6 @@ export declare const PluginConfigSchema: z.ZodObject<{
289
270
  storage_dir: z.ZodOptional<z.ZodString>;
290
271
  timeout: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
291
272
  }, z.core.$strip>>;
292
- clarificationGate: z.ZodOptional<z.ZodObject<{
293
- mode: z.ZodDefault<z.ZodEnum<{
294
- off: "off";
295
- "explicit-only": "explicit-only";
296
- auto: "auto";
297
- "auto-for-planning": "auto-for-planning";
298
- }>>;
299
- min_scope_signals: z.ZodDefault<z.ZodNumber>;
300
- hard_complex_signal_threshold: z.ZodDefault<z.ZodNumber>;
301
- explicit_keywords: z.ZodOptional<z.ZodArray<z.ZodString>>;
302
- planning_keywords: z.ZodOptional<z.ZodArray<z.ZodString>>;
303
- }, z.core.$strip>>;
304
273
  artifactStore: z.ZodOptional<z.ZodObject<{
305
274
  mode: z.ZodDefault<z.ZodEnum<{
306
275
  "thoth-mem": "thoth-mem";
@@ -1,7 +1,11 @@
1
+ import type { PluginInput } from '@opencode-ai/plugin';
1
2
  import type { DelegationConfig } from '../config';
2
3
  import { type DelegationListEntry, type DelegationRecord, type PersistedDelegationRecord } from './types';
3
4
  export interface DelegationManagerOptions {
4
5
  directory: string;
6
+ worktreeDirectory?: string;
7
+ projectName?: string;
8
+ shell?: PluginInput['$'];
5
9
  config?: DelegationConfig;
6
10
  getActiveTaskIds?: (rootSessionId: string) => Iterable<string>;
7
11
  }
@@ -10,11 +14,13 @@ export interface PersistDelegationInput {
10
14
  record: DelegationRecord;
11
15
  }
12
16
  export declare class DelegationManager {
13
- private readonly directory;
17
+ private readonly worktreeDirectory;
18
+ private readonly projectName;
19
+ private readonly shell?;
14
20
  private readonly config?;
15
21
  private readonly getActiveTaskIds?;
16
22
  constructor(options: DelegationManagerOptions);
17
- resolveProjectId(directory?: string): Promise<string | null>;
23
+ resolveProjectId(worktreeDirectory?: string): Promise<string | null>;
18
24
  createTaskId(rootSessionId: string): Promise<string>;
19
25
  persist(input: PersistDelegationInput): Promise<PersistedDelegationRecord | null>;
20
26
  read(taskId: string, rootSessionId: string): Promise<PersistedDelegationRecord | null>;
@@ -1 +1,10 @@
1
- export declare function getProjectId(directory: string, timeoutMs?: number): Promise<string | null>;
1
+ import type { PluginInput } from '@opencode-ai/plugin';
2
+ interface ProjectIdOptions {
3
+ worktreeDirectory: string;
4
+ projectName?: string;
5
+ shell?: PluginInput['$'];
6
+ timeoutMs?: number;
7
+ }
8
+ export declare function getProjectId(directory: string, timeoutMs?: number, projectName?: string, shell?: PluginInput['$']): Promise<string | null>;
9
+ export declare function getProjectId(options: ProjectIdOptions): Promise<string | null>;
10
+ export {};
@@ -4,9 +4,10 @@ import type { AutoUpdateCheckerOptions } from './types';
4
4
  * Creates an OpenCode hook that checks for plugin updates when a new session is created.
5
5
  * @param ctx The plugin input context.
6
6
  * @param options Configuration options for the update checker.
7
+ * @param shell The BunShell instance for running commands.
7
8
  * @returns A hook object for the session.created event.
8
9
  */
9
- export declare function createAutoUpdateCheckerHook(ctx: PluginInput, options?: AutoUpdateCheckerOptions): {
10
+ export declare function createAutoUpdateCheckerHook(ctx: PluginInput, options: AutoUpdateCheckerOptions | undefined, shell: PluginInput['$']): {
10
11
  event: ({ event }: {
11
12
  event: {
12
13
  type: string;
@@ -1,7 +1,6 @@
1
1
  export type { AutoUpdateCheckerOptions } from './auto-update-checker';
2
2
  export { createAutoUpdateCheckerHook } from './auto-update-checker';
3
3
  export { createChatHeadersHook } from './chat-headers';
4
- export { createClarificationGateHook } from './clarification-gate';
5
4
  export { createDelegateTaskRetryHook } from './delegate-task-retry';
6
5
  export { ForegroundFallbackManager, isRateLimitError, } from './foreground-fallback';
7
6
  export { createJsonErrorRecoveryHook } from './json-error-recovery';
@@ -1,4 +1,4 @@
1
- export declare const PHASE_REMINDER = "<reminder>Recall Workflow Rules:\nUnderstand \u2192 find the best path (delegate based on rules and parallelize independent work) \u2192 execute \u2192 verify.\nIf delegating, launch the specialist in the same turn you mention it.</reminder>";
1
+ export declare const PHASE_REMINDER = "<reminder>Recall Workflow Rules:\nUnderstand \u2192 find the best path (delegate based on rules and parallelize independent work) \u2192 execute \u2192 verify.\nIf delegating, launch the specialist in the same turn you mention it. If multiple delegations are independent, emit all tool calls in a single response \u2014 never serialize independent work across turns.</reminder>";
2
2
  interface MessageInfo {
3
3
  role: string;
4
4
  agent?: string;
@@ -1,6 +1,7 @@
1
1
  export declare const SDD_TOPIC_KEY_FORMAT = "sdd/{change}/{artifact}";
2
- export declare const FIRST_ACTION_INSTRUCTION = "FIRST ACTION REQUIRED: Call mem_session_summary with the content of the compacted summary. This preserves what was accomplished before compaction. Do this BEFORE any other work. Then call mem_context to recover additional context from previous sessions.";
2
+ export declare const FIRST_ACTION_INSTRUCTION = "FIRST ACTION REQUIRED: Call mem_session_summary with the content of the compacted summary. This preserves what was accomplished before compaction. Do this BEFORE any other work. Then call mem_context for a recent-session overview, and use the 3-layer recall protocol (mem_search with mode \"compact\" -> mem_timeline -> mem_get_observation) for precise retrieval.";
3
3
  export declare const SESSION_SUMMARY_TEMPLATE = "Use this exact structure for `mem_session_summary` content:\n\n## Goal\n[What we were working on this session]\n\n## Instructions\n[User preferences or constraints discovered during this session]\n\n## Discoveries\n- [Technical findings, gotchas, non-obvious learnings]\n\n## Accomplished\n- [Completed items with key details]\n\n## Next Steps\n- [What remains to be done]\n\n## Relevant Files\n- path/to/file.ts - [what it does or what changed]";
4
4
  export declare function buildCompactionReminder(sessionID: string): string;
5
5
  export declare function buildCompactorInstruction(project: string): string;
6
6
  export declare function buildMemoryInstructions(sessionID: string, project: string): string;
7
+ export declare function buildSaveNudge(): string;