oh-my-opencode-serverlocal 0.1.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/LICENSE +21 -0
- package/README.ja-JP.md +775 -0
- package/README.ko-KR.md +796 -0
- package/README.md +792 -0
- package/README.zh-CN.md +765 -0
- package/dist/agents/council.d.ts +27 -0
- package/dist/agents/councillor.d.ts +2 -0
- package/dist/agents/designer.d.ts +2 -0
- package/dist/agents/explorer.d.ts +2 -0
- package/dist/agents/fixer.d.ts +2 -0
- package/dist/agents/index.d.ts +31 -0
- package/dist/agents/librarian.d.ts +2 -0
- package/dist/agents/observer.d.ts +2 -0
- package/dist/agents/oracle.d.ts +2 -0
- package/dist/agents/orchestrator.d.ts +28 -0
- package/dist/agents/permissions.d.ts +10 -0
- package/dist/cli/background-subagents.d.ts +13 -0
- package/dist/cli/companion.d.ts +4 -0
- package/dist/cli/config-io.d.ts +25 -0
- package/dist/cli/config-manager.d.ts +4 -0
- package/dist/cli/custom-skills-registry.d.ts +18 -0
- package/dist/cli/custom-skills.d.ts +13 -0
- package/dist/cli/doctor.d.ts +38 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.js +3565 -0
- package/dist/cli/install.d.ts +7 -0
- package/dist/cli/model-key-normalization.d.ts +1 -0
- package/dist/cli/paths.d.ts +35 -0
- package/dist/cli/providers.d.ts +145 -0
- package/dist/cli/skills.d.ts +24 -0
- package/dist/cli/system.d.ts +6 -0
- package/dist/cli/types.d.ts +47 -0
- package/dist/companion/manager.d.ts +50 -0
- package/dist/companion/updater.d.ts +36 -0
- package/dist/config/agent-mcps.d.ts +11 -0
- package/dist/config/constants.d.ts +38 -0
- package/dist/config/council-schema.d.ts +137 -0
- package/dist/config/index.d.ts +5 -0
- package/dist/config/loader.d.ts +88 -0
- package/dist/config/runtime-preset.d.ts +11 -0
- package/dist/config/schema.d.ts +1107 -0
- package/dist/config/strip-orchestrator-model.d.ts +9 -0
- package/dist/config/utils.d.ts +18 -0
- package/dist/council/council-manager.d.ts +53 -0
- package/dist/council/index.d.ts +1 -0
- package/dist/hooks/apply-patch/codec.d.ts +7 -0
- package/dist/hooks/apply-patch/errors.d.ts +25 -0
- package/dist/hooks/apply-patch/execution-context.d.ts +27 -0
- package/dist/hooks/apply-patch/index.d.ts +15 -0
- package/dist/hooks/apply-patch/matching.d.ts +26 -0
- package/dist/hooks/apply-patch/operations.d.ts +3 -0
- package/dist/hooks/apply-patch/prepared-changes.d.ts +17 -0
- package/dist/hooks/apply-patch/resolution.d.ts +19 -0
- package/dist/hooks/apply-patch/rewrite.d.ts +7 -0
- package/dist/hooks/apply-patch/test-helpers.d.ts +6 -0
- package/dist/hooks/apply-patch/types.d.ts +80 -0
- package/dist/hooks/auto-update-checker/cache.d.ts +11 -0
- package/dist/hooks/auto-update-checker/checker.d.ts +38 -0
- package/dist/hooks/auto-update-checker/constants.d.ts +12 -0
- package/dist/hooks/auto-update-checker/index.d.ts +18 -0
- package/dist/hooks/auto-update-checker/skill-sync.d.ts +67 -0
- package/dist/hooks/auto-update-checker/types.d.ts +34 -0
- package/dist/hooks/chat-headers.d.ts +16 -0
- package/dist/hooks/command-hook-utils.d.ts +5 -0
- package/dist/hooks/deepwork/index.d.ts +13 -0
- package/dist/hooks/delegate-task-retry/hook.d.ts +8 -0
- package/dist/hooks/delegate-task-retry/patterns.d.ts +11 -0
- package/dist/hooks/filter-available-skills/index.d.ts +19 -0
- package/dist/hooks/foreground-fallback/index.d.ts +122 -0
- package/dist/hooks/image-hook.d.ts +8 -0
- package/dist/hooks/index.d.ts +16 -0
- package/dist/hooks/json-error-recovery/hook.d.ts +18 -0
- package/dist/hooks/loop-command/index.d.ts +13 -0
- package/dist/hooks/phase-reminder/index.d.ts +25 -0
- package/dist/hooks/post-file-tool-nudge/index.d.ts +23 -0
- package/dist/hooks/reflect/index.d.ts +13 -0
- package/dist/hooks/session-lifecycle.d.ts +10 -0
- package/dist/hooks/task-session-manager/index.d.ts +58 -0
- package/dist/hooks/task-session-manager/pending-call-tracker.d.ts +13 -0
- package/dist/hooks/task-session-manager/task-context-tracker.d.ts +14 -0
- package/dist/hooks/types.d.ts +26 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +39519 -0
- package/dist/interview/dashboard-manager.d.ts +21 -0
- package/dist/interview/dashboard.d.ts +67 -0
- package/dist/interview/document.d.ts +29 -0
- package/dist/interview/helpers.d.ts +10 -0
- package/dist/interview/index.d.ts +1 -0
- package/dist/interview/manager.d.ts +21 -0
- package/dist/interview/parser.d.ts +11 -0
- package/dist/interview/prompts.d.ts +7 -0
- package/dist/interview/server.d.ts +15 -0
- package/dist/interview/service.d.ts +45 -0
- package/dist/interview/session-server.d.ts +21 -0
- package/dist/interview/types.d.ts +111 -0
- package/dist/interview/ui.d.ts +11 -0
- package/dist/loop/loop-session.d.ts +64 -0
- package/dist/mcp/context7.d.ts +6 -0
- package/dist/mcp/grep-app.d.ts +6 -0
- package/dist/mcp/index.d.ts +8 -0
- package/dist/mcp/types.d.ts +12 -0
- package/dist/mcp/websearch.d.ts +9 -0
- package/dist/multiplexer/cmux/close-policy.d.ts +20 -0
- package/dist/multiplexer/cmux/index.d.ts +102 -0
- package/dist/multiplexer/cmux/session-lifecycle.d.ts +92 -0
- package/dist/multiplexer/cmux/session-state.d.ts +45 -0
- package/dist/multiplexer/factory.d.ts +17 -0
- package/dist/multiplexer/herdr/index.d.ts +35 -0
- package/dist/multiplexer/index.d.ts +12 -0
- package/dist/multiplexer/session-manager.d.ts +69 -0
- package/dist/multiplexer/shared.d.ts +31 -0
- package/dist/multiplexer/tmux/index.d.ts +26 -0
- package/dist/multiplexer/types.d.ts +57 -0
- package/dist/multiplexer/zellij/index.d.ts +47 -0
- package/dist/tools/acp-run.d.ts +3 -0
- package/dist/tools/ast-grep/cli.d.ts +15 -0
- package/dist/tools/ast-grep/constants.d.ts +25 -0
- package/dist/tools/ast-grep/downloader.d.ts +5 -0
- package/dist/tools/ast-grep/index.d.ts +10 -0
- package/dist/tools/ast-grep/tools.d.ts +3 -0
- package/dist/tools/ast-grep/types.d.ts +30 -0
- package/dist/tools/ast-grep/utils.d.ts +4 -0
- package/dist/tools/cancel-task.d.ts +16 -0
- package/dist/tools/council.d.ts +10 -0
- package/dist/tools/index.d.ts +7 -0
- package/dist/tools/preset-manager.d.ts +26 -0
- package/dist/tools/smartfetch/binary.d.ts +3 -0
- package/dist/tools/smartfetch/cache.d.ts +6 -0
- package/dist/tools/smartfetch/constants.d.ts +12 -0
- package/dist/tools/smartfetch/index.d.ts +3 -0
- package/dist/tools/smartfetch/network.d.ts +38 -0
- package/dist/tools/smartfetch/secondary-model.d.ts +35 -0
- package/dist/tools/smartfetch/tool.d.ts +3 -0
- package/dist/tools/smartfetch/types.d.ts +122 -0
- package/dist/tools/smartfetch/utils.d.ts +20 -0
- package/dist/tui-state.d.ts +18 -0
- package/dist/tui.d.ts +13 -0
- package/dist/tui.js +1112 -0
- package/dist/utils/agent-variant.d.ts +23 -0
- package/dist/utils/background-job-board.d.ts +113 -0
- package/dist/utils/background-job-coordinator.d.ts +72 -0
- package/dist/utils/background-job-store.d.ts +46 -0
- package/dist/utils/compat.d.ts +29 -0
- package/dist/utils/councillor-models.d.ts +20 -0
- package/dist/utils/env.d.ts +3 -0
- package/dist/utils/escape-html.d.ts +1 -0
- package/dist/utils/frontmatter.d.ts +6 -0
- package/dist/utils/guards.d.ts +4 -0
- package/dist/utils/index.d.ts +10 -0
- package/dist/utils/internal-initiator.d.ts +11 -0
- package/dist/utils/logger.d.ts +6 -0
- package/dist/utils/polling.d.ts +21 -0
- package/dist/utils/session.d.ts +75 -0
- package/dist/utils/subagent-depth.d.ts +35 -0
- package/dist/utils/system-collapse.d.ts +6 -0
- package/dist/utils/task.d.ts +20 -0
- package/dist/utils/zip-extractor.d.ts +1 -0
- package/package.json +108 -0
- package/src/companion/companion-manifest.json +12 -0
- package/src/skills/clonedeps/README.md +23 -0
- package/src/skills/clonedeps/SKILL.md +240 -0
- package/src/skills/clonedeps/codemap.md +32 -0
- package/src/skills/codemap/README.md +59 -0
- package/src/skills/codemap/SKILL.md +163 -0
- package/src/skills/codemap/codemap.md +36 -0
- package/src/skills/codemap/scripts/codemap.mjs +483 -0
- package/src/skills/codemap/scripts/codemap.test.ts +129 -0
- package/src/skills/codemap.md +78 -0
- package/src/skills/deepwork/SKILL.md +122 -0
- package/src/skills/loop-engineering/SKILL.md +30 -0
- package/src/skills/oh-my-opencode-slim/SKILL.md +326 -0
- package/src/skills/reflect/SKILL.md +326 -0
- package/src/skills/simplify/README.md +19 -0
- package/src/skills/simplify/SKILL.md +138 -0
- package/src/skills/simplify/codemap.md +36 -0
- package/src/skills/verification-planning/SKILL.md +102 -0
- package/src/skills/worktrees/SKILL.md +171 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { PluginInput } from '@opencode-ai/plugin';
|
|
2
|
+
import type { PluginConfig } from '../config';
|
|
3
|
+
export declare function createDashboardManager(ctx: PluginInput, config: PluginConfig, dashboardPort: number, outputFolder: string): {
|
|
4
|
+
registerCommand: (config: Record<string, unknown>) => void;
|
|
5
|
+
handleCommandExecuteBefore: (input: {
|
|
6
|
+
command: string;
|
|
7
|
+
sessionID: string;
|
|
8
|
+
arguments: string;
|
|
9
|
+
}, output: {
|
|
10
|
+
parts: Array<{
|
|
11
|
+
type: string;
|
|
12
|
+
text?: string;
|
|
13
|
+
}>;
|
|
14
|
+
}) => Promise<void>;
|
|
15
|
+
handleEvent: (input: {
|
|
16
|
+
event: {
|
|
17
|
+
type: string;
|
|
18
|
+
properties?: Record<string, unknown>;
|
|
19
|
+
};
|
|
20
|
+
}) => Promise<void>;
|
|
21
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { InterviewStateEntry } from './types';
|
|
2
|
+
export declare function readDashboardAuthFile(port: number): Promise<{
|
|
3
|
+
token: string;
|
|
4
|
+
pid: number;
|
|
5
|
+
startedAt: number;
|
|
6
|
+
} | null>;
|
|
7
|
+
interface RegisteredSession {
|
|
8
|
+
sessionID: string;
|
|
9
|
+
directory: string;
|
|
10
|
+
pid: number;
|
|
11
|
+
registeredAt: number;
|
|
12
|
+
}
|
|
13
|
+
export declare const DEFAULT_DASHBOARD_PORT = 43211;
|
|
14
|
+
export interface DashboardConfig {
|
|
15
|
+
port: number;
|
|
16
|
+
outputFolder: string;
|
|
17
|
+
sessionClient?: {
|
|
18
|
+
list: (params?: Record<string, unknown>) => Promise<{
|
|
19
|
+
data?: Array<{
|
|
20
|
+
directory?: string;
|
|
21
|
+
time?: {
|
|
22
|
+
updated?: number;
|
|
23
|
+
};
|
|
24
|
+
}>;
|
|
25
|
+
}>;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export declare function createDashboardServer(config: DashboardConfig): {
|
|
29
|
+
start: () => Promise<string>;
|
|
30
|
+
close: () => void;
|
|
31
|
+
registerSession: (info: RegisteredSession) => void;
|
|
32
|
+
removeSession: (sessionID: string) => void;
|
|
33
|
+
pushState: (entry: InterviewStateEntry) => void;
|
|
34
|
+
getState: (interviewId: string) => InterviewStateEntry | undefined;
|
|
35
|
+
storeAnswers: (interviewId: string, answers: Array<{
|
|
36
|
+
questionId: string;
|
|
37
|
+
answer: string;
|
|
38
|
+
}>) => void;
|
|
39
|
+
getPendingAnswers: (interviewId: string) => Array<{
|
|
40
|
+
questionId: string;
|
|
41
|
+
answer: string;
|
|
42
|
+
}> | null;
|
|
43
|
+
consumePendingAnswers: (interviewId: string) => Array<{
|
|
44
|
+
questionId: string;
|
|
45
|
+
answer: string;
|
|
46
|
+
}> | null;
|
|
47
|
+
consumeNudgeAction: (interviewId: string) => 'more-questions' | 'confirm-complete' | null;
|
|
48
|
+
consumeBlockComment: (interviewId: string) => {
|
|
49
|
+
section: string;
|
|
50
|
+
comment: string;
|
|
51
|
+
} | null;
|
|
52
|
+
consumeChatMessage: (interviewId: string) => string | null;
|
|
53
|
+
authToken: string;
|
|
54
|
+
discoverSessionDirectories: () => Promise<void>;
|
|
55
|
+
addManualFolder: (dir: string) => void;
|
|
56
|
+
removeManualFolder: (dir: string) => void;
|
|
57
|
+
getManualFolders: () => string[];
|
|
58
|
+
setScanDays: (days: number) => void;
|
|
59
|
+
getScanDays: () => number;
|
|
60
|
+
refreshFiles: () => Promise<void>;
|
|
61
|
+
};
|
|
62
|
+
export declare function probeDashboard(port: number): Promise<{
|
|
63
|
+
alive: boolean;
|
|
64
|
+
timestamp: number;
|
|
65
|
+
}>;
|
|
66
|
+
export declare function tryBecomeDashboard(config: DashboardConfig, maxAttempts?: number): Promise<ReturnType<typeof createDashboardServer> | null>;
|
|
67
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { parseFrontmatter as sharedParseFrontmatter } from '../utils/frontmatter';
|
|
2
|
+
import type { InterviewAnswer, InterviewQuestion, InterviewRecord, SpecBlock } from './types';
|
|
3
|
+
export declare const DEFAULT_OUTPUT_FOLDER = "interview";
|
|
4
|
+
export declare function normalizeOutputFolder(outputFolder: string): string;
|
|
5
|
+
export declare function createInterviewDirectoryPath(directory: string, outputFolder: string): string;
|
|
6
|
+
export declare function createInterviewFilePath(directory: string, outputFolder: string, idea: string): string;
|
|
7
|
+
export declare function relativeInterviewPath(directory: string, filePath: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* Resolve a user-provided value to an existing .md file path.
|
|
10
|
+
* Checks absolute paths, relative paths, and output-folder-relative paths.
|
|
11
|
+
* Returns null if no matching file is found.
|
|
12
|
+
*/
|
|
13
|
+
export declare function resolveExistingInterviewPath(directory: string, outputFolder: string, value: string): string | null;
|
|
14
|
+
export declare function slugify(value: string): string;
|
|
15
|
+
export declare function extractSummarySection(document: string): string;
|
|
16
|
+
export declare function extractTitle(document: string): string;
|
|
17
|
+
export declare function buildInterviewDocument(idea: string, summary: string, history: string, meta?: {
|
|
18
|
+
sessionID?: string;
|
|
19
|
+
baseMessageCount?: number;
|
|
20
|
+
owner?: string;
|
|
21
|
+
tags?: string[];
|
|
22
|
+
}): string;
|
|
23
|
+
/** Parse frontmatter from a .md file. Returns null if no frontmatter. */
|
|
24
|
+
export declare const parseFrontmatter: typeof sharedParseFrontmatter;
|
|
25
|
+
export declare function ensureInterviewFile(record: InterviewRecord): Promise<void>;
|
|
26
|
+
export declare function readInterviewDocument(record: InterviewRecord): Promise<string>;
|
|
27
|
+
export declare function rewriteInterviewDocument(record: InterviewRecord, summary: string): Promise<string>;
|
|
28
|
+
export declare function appendInterviewAnswers(record: InterviewRecord, questions: InterviewQuestion[], answers: InterviewAnswer[]): Promise<void>;
|
|
29
|
+
export declare function parseSpecBlocks(markdown: string): SpecBlock[];
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
+
export declare function sendJson(response: ServerResponse, status: number, value: unknown): void;
|
|
3
|
+
export declare function sendHtml(response: ServerResponse, html: string): void;
|
|
4
|
+
export declare function isValidId(id: string): boolean;
|
|
5
|
+
export declare function extractResumeSlug(interviewId: string): string;
|
|
6
|
+
/**
|
|
7
|
+
* Read and parse JSON body from an HTTP request with size limit.
|
|
8
|
+
* Destroys the request if the body exceeds MAX_BODY_SIZE.
|
|
9
|
+
*/
|
|
10
|
+
export declare function readJsonBody(request: IncomingMessage): Promise<unknown>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createInterviewManager } from './manager';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { PluginInput } from '@opencode-ai/plugin';
|
|
2
|
+
import type { PluginConfig } from '../config';
|
|
3
|
+
export declare function createInterviewManager(ctx: PluginInput, config: PluginConfig): {
|
|
4
|
+
registerCommand: (config: Record<string, unknown>) => void;
|
|
5
|
+
handleCommandExecuteBefore: (input: {
|
|
6
|
+
command: string;
|
|
7
|
+
sessionID: string;
|
|
8
|
+
arguments: string;
|
|
9
|
+
}, output: {
|
|
10
|
+
parts: Array<{
|
|
11
|
+
type: string;
|
|
12
|
+
text?: string;
|
|
13
|
+
}>;
|
|
14
|
+
}) => Promise<void>;
|
|
15
|
+
handleEvent: (input: {
|
|
16
|
+
event: {
|
|
17
|
+
type: string;
|
|
18
|
+
properties?: Record<string, unknown>;
|
|
19
|
+
};
|
|
20
|
+
}) => Promise<void>;
|
|
21
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { InterviewAssistantState, InterviewMessage } from './types';
|
|
2
|
+
export declare function flattenMessage(message: InterviewMessage): string;
|
|
3
|
+
export declare function buildFallbackState(messages: InterviewMessage[]): InterviewAssistantState;
|
|
4
|
+
export declare function parseAssistantState(text: string, maxQuestions?: number): {
|
|
5
|
+
state: InterviewAssistantState | null;
|
|
6
|
+
error?: string;
|
|
7
|
+
};
|
|
8
|
+
export declare function findLatestAssistantState(messages: InterviewMessage[], maxQuestions?: number): {
|
|
9
|
+
state: InterviewAssistantState | null;
|
|
10
|
+
latestAssistantError?: string;
|
|
11
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { InterviewQuestion } from './types';
|
|
2
|
+
export declare function buildKickoffPrompt(idea: string, maxQuestions: number): string;
|
|
3
|
+
export declare function buildResumePrompt(document: string, maxQuestions: number): string;
|
|
4
|
+
export declare function buildAnswerPrompt(answers: Array<{
|
|
5
|
+
questionId: string;
|
|
6
|
+
answer: string;
|
|
7
|
+
}>, questions: InterviewQuestion[], maxQuestions: number): string;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { InterviewAnswer, InterviewFileItem, InterviewListItem, InterviewState } from './types';
|
|
2
|
+
export declare function createInterviewServer(deps: {
|
|
3
|
+
getState: (interviewId: string) => Promise<InterviewState>;
|
|
4
|
+
listInterviewFiles: () => Promise<InterviewFileItem[]>;
|
|
5
|
+
listInterviews: () => InterviewListItem[];
|
|
6
|
+
submitAnswers: (interviewId: string, answers: InterviewAnswer[]) => Promise<void>;
|
|
7
|
+
submitBlockComment: (interviewId: string, section: string, comment: string) => Promise<void>;
|
|
8
|
+
submitChat: (interviewId: string, message: string) => Promise<void>;
|
|
9
|
+
handleNudgeAction: (interviewId: string, action: 'more-questions' | 'confirm-complete') => Promise<void>;
|
|
10
|
+
outputFolder: string;
|
|
11
|
+
port: number;
|
|
12
|
+
}): {
|
|
13
|
+
ensureStarted: () => Promise<string>;
|
|
14
|
+
close: () => void;
|
|
15
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { PluginInput } from '@opencode-ai/plugin';
|
|
2
|
+
import type { InterviewConfig } from '../config';
|
|
3
|
+
import type { InterviewAnswer, InterviewFileItem, InterviewListItem, InterviewRecord, InterviewState } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* Cap on retained abandoned interview records. Abandoned interviews are kept
|
|
6
|
+
* briefly so a still-open browser tab can render their final state, but
|
|
7
|
+
* without a bound the `interviewsById` and `browserOpened` collections grow
|
|
8
|
+
* for the life of a long-running session/dashboard process.
|
|
9
|
+
*/
|
|
10
|
+
export declare const MAX_RETAINED_ABANDONED = 50;
|
|
11
|
+
export declare function createInterviewService(ctx: PluginInput, config?: InterviewConfig, deps?: {
|
|
12
|
+
openBrowser?: (url: string) => void;
|
|
13
|
+
env?: NodeJS.ProcessEnv;
|
|
14
|
+
}): {
|
|
15
|
+
setBaseUrlResolver: (resolver: () => Promise<string>) => void;
|
|
16
|
+
setStatePushCallback: (callback: (interviewId: string, state: InterviewState) => void) => void;
|
|
17
|
+
setOnInterviewCreated: (callback: (interview: InterviewRecord) => void) => void;
|
|
18
|
+
getActiveInterviewId: (sessionID: string) => string | null;
|
|
19
|
+
registerCommand: (config: Record<string, unknown>) => void;
|
|
20
|
+
handleCommandExecuteBefore: (input: {
|
|
21
|
+
command: string;
|
|
22
|
+
sessionID: string;
|
|
23
|
+
arguments: string;
|
|
24
|
+
}, output: {
|
|
25
|
+
parts: Array<{
|
|
26
|
+
type: string;
|
|
27
|
+
text?: string;
|
|
28
|
+
synthetic?: boolean;
|
|
29
|
+
metadata?: Record<string, unknown>;
|
|
30
|
+
}>;
|
|
31
|
+
}) => Promise<void>;
|
|
32
|
+
handleEvent: (input: {
|
|
33
|
+
event: {
|
|
34
|
+
type: string;
|
|
35
|
+
properties?: Record<string, unknown>;
|
|
36
|
+
};
|
|
37
|
+
}) => Promise<void>;
|
|
38
|
+
getInterviewState: (interviewId: string) => Promise<InterviewState>;
|
|
39
|
+
listInterviewFiles: () => Promise<InterviewFileItem[]>;
|
|
40
|
+
listInterviews: () => InterviewListItem[];
|
|
41
|
+
submitAnswers: (interviewId: string, answers: InterviewAnswer[]) => Promise<void>;
|
|
42
|
+
submitBlockComment: (interviewId: string, section: string, comment: string) => Promise<void>;
|
|
43
|
+
submitChat: (interviewId: string, message: string) => Promise<void>;
|
|
44
|
+
handleNudgeAction: (interviewId: string, action: 'more-questions' | 'confirm-complete') => Promise<void>;
|
|
45
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { PluginInput } from '@opencode-ai/plugin';
|
|
2
|
+
import type { InterviewConfig } from '../config';
|
|
3
|
+
export declare function createPerSessionInterviewServer(ctx: PluginInput, interviewConfig: InterviewConfig | undefined, outputFolder: string): {
|
|
4
|
+
registerCommand: (config: Record<string, unknown>) => void;
|
|
5
|
+
handleCommandExecuteBefore: (input: {
|
|
6
|
+
command: string;
|
|
7
|
+
sessionID: string;
|
|
8
|
+
arguments: string;
|
|
9
|
+
}, output: {
|
|
10
|
+
parts: Array<{
|
|
11
|
+
type: string;
|
|
12
|
+
text?: string;
|
|
13
|
+
}>;
|
|
14
|
+
}) => Promise<void>;
|
|
15
|
+
handleEvent: (input: {
|
|
16
|
+
event: {
|
|
17
|
+
type: string;
|
|
18
|
+
properties?: Record<string, unknown>;
|
|
19
|
+
};
|
|
20
|
+
}) => Promise<void>;
|
|
21
|
+
};
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export interface InterviewQuestion {
|
|
3
|
+
id: string;
|
|
4
|
+
question: string;
|
|
5
|
+
options: string[];
|
|
6
|
+
suggested?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface InterviewAnswer {
|
|
9
|
+
questionId: string;
|
|
10
|
+
answer: string;
|
|
11
|
+
}
|
|
12
|
+
export interface InterviewAssistantState {
|
|
13
|
+
summary: string;
|
|
14
|
+
title?: string;
|
|
15
|
+
questions: InterviewQuestion[];
|
|
16
|
+
}
|
|
17
|
+
/** Raw question object from LLM output - loose, everything optional. */
|
|
18
|
+
export declare const RawQuestionSchema: z.ZodObject<{
|
|
19
|
+
id: z.ZodOptional<z.ZodString>;
|
|
20
|
+
question: z.ZodOptional<z.ZodString>;
|
|
21
|
+
options: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
|
|
22
|
+
suggested: z.ZodOptional<z.ZodUnknown>;
|
|
23
|
+
}, z.core.$strip>;
|
|
24
|
+
/** Raw interview_state block from LLM output. */
|
|
25
|
+
export declare const RawInterviewStateSchema: z.ZodObject<{
|
|
26
|
+
summary: z.ZodOptional<z.ZodUnknown>;
|
|
27
|
+
title: z.ZodOptional<z.ZodUnknown>;
|
|
28
|
+
questions: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
|
|
29
|
+
}, z.core.$strip>;
|
|
30
|
+
export interface InterviewRecord {
|
|
31
|
+
id: string;
|
|
32
|
+
sessionID: string;
|
|
33
|
+
idea: string;
|
|
34
|
+
markdownPath: string;
|
|
35
|
+
createdAt: string;
|
|
36
|
+
abandonedAt?: string;
|
|
37
|
+
abandonedOrder?: number;
|
|
38
|
+
status: 'active' | 'abandoned';
|
|
39
|
+
baseMessageCount: number;
|
|
40
|
+
}
|
|
41
|
+
export interface InterviewMessagePart {
|
|
42
|
+
type?: string;
|
|
43
|
+
text?: string;
|
|
44
|
+
}
|
|
45
|
+
export interface InterviewMessage {
|
|
46
|
+
info?: {
|
|
47
|
+
role?: string;
|
|
48
|
+
[key: string]: unknown;
|
|
49
|
+
};
|
|
50
|
+
parts?: InterviewMessagePart[];
|
|
51
|
+
}
|
|
52
|
+
export interface InterviewListItem {
|
|
53
|
+
id: string;
|
|
54
|
+
idea: string;
|
|
55
|
+
status: InterviewRecord['status'];
|
|
56
|
+
createdAt: string;
|
|
57
|
+
}
|
|
58
|
+
export interface InterviewFileItem {
|
|
59
|
+
fileName: string;
|
|
60
|
+
resumeCommand: string;
|
|
61
|
+
title: string;
|
|
62
|
+
summary: string;
|
|
63
|
+
sessionID?: string;
|
|
64
|
+
directory?: string;
|
|
65
|
+
}
|
|
66
|
+
export interface SpecBlock {
|
|
67
|
+
id: string;
|
|
68
|
+
title: string;
|
|
69
|
+
content: string;
|
|
70
|
+
}
|
|
71
|
+
export interface InterviewState {
|
|
72
|
+
interview: InterviewRecord;
|
|
73
|
+
url: string;
|
|
74
|
+
markdownPath: string;
|
|
75
|
+
mode: 'awaiting-agent' | 'awaiting-user' | 'abandoned' | 'completed' | 'error' | 'session-disconnected';
|
|
76
|
+
lastParseError?: string;
|
|
77
|
+
isBusy: boolean;
|
|
78
|
+
summary: string;
|
|
79
|
+
questions: InterviewQuestion[];
|
|
80
|
+
document: string;
|
|
81
|
+
blocks: SpecBlock[];
|
|
82
|
+
}
|
|
83
|
+
/** Wire format for dashboard state cache entries. */
|
|
84
|
+
export interface InterviewStateEntry {
|
|
85
|
+
interviewId: string;
|
|
86
|
+
sessionID: string;
|
|
87
|
+
idea: string;
|
|
88
|
+
mode: 'awaiting-agent' | 'awaiting-user' | 'abandoned' | 'completed' | 'error' | 'session-disconnected';
|
|
89
|
+
summary: string;
|
|
90
|
+
title: string;
|
|
91
|
+
questions: Array<{
|
|
92
|
+
id: string;
|
|
93
|
+
question: string;
|
|
94
|
+
options?: string[];
|
|
95
|
+
suggested?: string;
|
|
96
|
+
}>;
|
|
97
|
+
pendingAnswers: Array<{
|
|
98
|
+
questionId: string;
|
|
99
|
+
answer: string;
|
|
100
|
+
}> | null;
|
|
101
|
+
lastUpdatedAt: number;
|
|
102
|
+
filePath: string;
|
|
103
|
+
nudgeAction: 'more-questions' | 'confirm-complete' | null;
|
|
104
|
+
pendingBlockComment: {
|
|
105
|
+
section: string;
|
|
106
|
+
comment: string;
|
|
107
|
+
} | null;
|
|
108
|
+
pendingChatMessage: string | null;
|
|
109
|
+
document?: string;
|
|
110
|
+
blocks?: SpecBlock[];
|
|
111
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { InterviewFileItem, InterviewListItem } from './types';
|
|
2
|
+
interface DashboardInterviewItem extends InterviewListItem {
|
|
3
|
+
url: string;
|
|
4
|
+
mode: string;
|
|
5
|
+
resumeSlug: string;
|
|
6
|
+
sessionID?: string;
|
|
7
|
+
directory?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function renderDashboardPage(interviews: DashboardInterviewItem[], files: InterviewFileItem[], outputFolder: string): string;
|
|
10
|
+
export declare function renderInterviewPage(interviewId: string, resumeSlug: string): string;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export declare function loopDirname(loopID: string, goal: string): string;
|
|
2
|
+
export type LoopPhase = 'executing' | 'verifying' | 'done' | 'escalated' | 'cancelled';
|
|
3
|
+
export type ExecuteAgent = 'fixer' | 'designer' | 'explorer' | 'librarian';
|
|
4
|
+
export type VerifyAgent = 'oracle' | 'observer' | 'test';
|
|
5
|
+
export type SuccessCriterion = {
|
|
6
|
+
type: 'test';
|
|
7
|
+
command: string;
|
|
8
|
+
} | {
|
|
9
|
+
type: 'build';
|
|
10
|
+
command: string;
|
|
11
|
+
} | {
|
|
12
|
+
type: 'lint';
|
|
13
|
+
command: string;
|
|
14
|
+
} | {
|
|
15
|
+
type: 'fileExists';
|
|
16
|
+
path: string;
|
|
17
|
+
} | {
|
|
18
|
+
type: 'command';
|
|
19
|
+
command: string;
|
|
20
|
+
expectExitCode?: number;
|
|
21
|
+
} | {
|
|
22
|
+
type: 'oracle';
|
|
23
|
+
} | {
|
|
24
|
+
type: 'observer';
|
|
25
|
+
} | {
|
|
26
|
+
type: 'manual';
|
|
27
|
+
};
|
|
28
|
+
export interface LoopDefinition {
|
|
29
|
+
goal: string;
|
|
30
|
+
successCriteria: string;
|
|
31
|
+
success: SuccessCriterion;
|
|
32
|
+
maxAttempts: number;
|
|
33
|
+
executeAgent: ExecuteAgent;
|
|
34
|
+
verifyAgent: VerifyAgent;
|
|
35
|
+
contextFiles?: string[];
|
|
36
|
+
parentSessionID?: string;
|
|
37
|
+
}
|
|
38
|
+
export type VerificationResult = {
|
|
39
|
+
passed: true;
|
|
40
|
+
reason: string;
|
|
41
|
+
} | {
|
|
42
|
+
passed: false;
|
|
43
|
+
reason: string;
|
|
44
|
+
suggestedFix?: string;
|
|
45
|
+
};
|
|
46
|
+
export interface AttemptRecord {
|
|
47
|
+
attemptNumber: number;
|
|
48
|
+
executionResult: string;
|
|
49
|
+
verificationResult: VerificationResult;
|
|
50
|
+
artifactPaths?: string[];
|
|
51
|
+
}
|
|
52
|
+
export interface LoopSession {
|
|
53
|
+
loopID: string;
|
|
54
|
+
definition: LoopDefinition;
|
|
55
|
+
currentPhase: LoopPhase;
|
|
56
|
+
attempts: number;
|
|
57
|
+
activeJobID?: string;
|
|
58
|
+
history: AttemptRecord[];
|
|
59
|
+
historyDir: string;
|
|
60
|
+
manualReviewPending: boolean;
|
|
61
|
+
}
|
|
62
|
+
export declare function createLoopSession(definition: LoopDefinition, loopID: string): LoopSession;
|
|
63
|
+
export declare function compactAttempt(attempt: AttemptRecord): string;
|
|
64
|
+
export declare function writeHistoryFile(session: LoopSession): void;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { WebsearchConfig } from '../config';
|
|
2
|
+
import type { McpConfig } from './types';
|
|
3
|
+
export type { LocalMcpConfig, McpConfig, RemoteMcpConfig } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* Creates MCP configurations, excluding disabled ones.
|
|
6
|
+
* Accepts an optional websearchConfig to override the default Exa provider.
|
|
7
|
+
*/
|
|
8
|
+
export declare function createBuiltinMcps(disabledMcps?: readonly string[], websearchConfig?: WebsearchConfig): Record<string, McpConfig>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type RemoteMcpConfig = {
|
|
2
|
+
type: 'remote';
|
|
3
|
+
url: string;
|
|
4
|
+
headers?: Record<string, string>;
|
|
5
|
+
oauth?: false;
|
|
6
|
+
};
|
|
7
|
+
export type LocalMcpConfig = {
|
|
8
|
+
type: 'local';
|
|
9
|
+
command: string[];
|
|
10
|
+
environment?: Record<string, string>;
|
|
11
|
+
};
|
|
12
|
+
export type McpConfig = RemoteMcpConfig | LocalMcpConfig;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { WebsearchConfig } from '../config';
|
|
2
|
+
import type { RemoteMcpConfig } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Creates a websearch MCP config based on the provided configuration.
|
|
5
|
+
* Supports Exa (default) and Tavily providers.
|
|
6
|
+
* @see https://exa.ai @see https://tavily.com
|
|
7
|
+
*/
|
|
8
|
+
export declare function createWebsearchConfig(config?: WebsearchConfig): RemoteMcpConfig;
|
|
9
|
+
export declare const websearch: RemoteMcpConfig;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type CmuxCloseReason = 'idle' | 'deleted' | 'cleanup';
|
|
2
|
+
export interface CmuxCloseIntent {
|
|
3
|
+
reason: CmuxCloseReason;
|
|
4
|
+
expectedActivityVersion: number;
|
|
5
|
+
attempts: number;
|
|
6
|
+
deadline: number;
|
|
7
|
+
phase: 'pending' | 'cooldown';
|
|
8
|
+
nextAttemptAt: number;
|
|
9
|
+
cooldowns: number;
|
|
10
|
+
}
|
|
11
|
+
export declare class CmuxClosePolicy {
|
|
12
|
+
private readonly budgetMs;
|
|
13
|
+
private readonly maxAttempts;
|
|
14
|
+
constructor(budgetMs?: number, maxAttempts?: number);
|
|
15
|
+
request(reason: CmuxCloseReason, version: number, now: number, current?: CmuxCloseIntent): CmuxCloseIntent;
|
|
16
|
+
activity(intent?: CmuxCloseIntent): CmuxCloseIntent | undefined;
|
|
17
|
+
failed(intent: CmuxCloseIntent, now: number): CmuxCloseIntent;
|
|
18
|
+
resume(intent: CmuxCloseIntent, now: number): CmuxCloseIntent;
|
|
19
|
+
complete(): undefined;
|
|
20
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import type { MultiplexerLayout } from '../../config/schema';
|
|
2
|
+
import { crossSpawn } from '../../utils/compat';
|
|
3
|
+
import type { Multiplexer, PaneResult } from '../types';
|
|
4
|
+
export interface CmuxReadinessOptions {
|
|
5
|
+
checkSessionReady?: (url: URL, sessionId: string, signal: AbortSignal) => Promise<boolean>;
|
|
6
|
+
delay?: (milliseconds: number) => Promise<void>;
|
|
7
|
+
readinessAttemptTimeoutMs?: number;
|
|
8
|
+
opencodeBinary?: string;
|
|
9
|
+
pathExists?: (path: string) => boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface CommandResult {
|
|
12
|
+
exitCode: number;
|
|
13
|
+
stdout: string;
|
|
14
|
+
stderr: string;
|
|
15
|
+
}
|
|
16
|
+
export interface CommandRunner {
|
|
17
|
+
run(argv: string[]): Promise<CommandResult>;
|
|
18
|
+
}
|
|
19
|
+
export interface CmuxIdentity {
|
|
20
|
+
workspaceId: string;
|
|
21
|
+
paneId: string;
|
|
22
|
+
surfaceId: string;
|
|
23
|
+
socketPath: string;
|
|
24
|
+
}
|
|
25
|
+
export interface CmuxClient {
|
|
26
|
+
version(): Promise<string | null>;
|
|
27
|
+
getVersionError?(): 'unavailable' | 'hard';
|
|
28
|
+
identify(): Promise<CmuxIdentity | null>;
|
|
29
|
+
getIdentifyError?(): 'unavailable' | 'hard';
|
|
30
|
+
createSurface(input: {
|
|
31
|
+
workspaceId: string;
|
|
32
|
+
targetSurfaceId: string;
|
|
33
|
+
direction: 'right' | 'down';
|
|
34
|
+
focus: false;
|
|
35
|
+
}, socketPath?: string): Promise<{
|
|
36
|
+
paneId: string;
|
|
37
|
+
surfaceId: string;
|
|
38
|
+
} | null>;
|
|
39
|
+
getCreateError?(): 'not_found' | 'unavailable' | 'invalid_state' | 'hard';
|
|
40
|
+
respawnSurface(workspaceId: string, surfaceId: string, command: string, socketPath?: string): Promise<boolean>;
|
|
41
|
+
closeSurface(workspaceId: string, surfaceId: string, socketPath?: string): Promise<'closed' | 'not_found' | 'failed'>;
|
|
42
|
+
equalizeSplits(params: {
|
|
43
|
+
workspace_id: string;
|
|
44
|
+
orientation: 'vertical';
|
|
45
|
+
}, socketPath?: string): Promise<boolean>;
|
|
46
|
+
}
|
|
47
|
+
export declare class CmuxMultiplexer implements Multiplexer {
|
|
48
|
+
private readonly client;
|
|
49
|
+
readonly type: "cmux";
|
|
50
|
+
private versionAvailable;
|
|
51
|
+
private availabilityError;
|
|
52
|
+
private readonly checkSessionReady;
|
|
53
|
+
private readonly delay;
|
|
54
|
+
private readonly readinessAttemptTimeoutMs;
|
|
55
|
+
private readonly opencodeBinary;
|
|
56
|
+
constructor(client?: CmuxClient, options?: CmuxReadinessOptions);
|
|
57
|
+
isAvailable(): Promise<boolean>;
|
|
58
|
+
isInsideSession(): boolean;
|
|
59
|
+
spawnPane(sessionId: string, _description: string, serverUrl: string, directory: string): Promise<PaneResult>;
|
|
60
|
+
closePane(paneId: string): Promise<boolean>;
|
|
61
|
+
applyLayout(_layout: MultiplexerLayout, _mainPaneSize: number): Promise<void>;
|
|
62
|
+
private cleanupPane;
|
|
63
|
+
private waitForSession;
|
|
64
|
+
private equalize;
|
|
65
|
+
}
|
|
66
|
+
export declare class SpawnCommandRunner implements CommandRunner {
|
|
67
|
+
private readonly timeoutMs;
|
|
68
|
+
private readonly spawn;
|
|
69
|
+
constructor(timeoutMs?: number, spawn?: typeof crossSpawn);
|
|
70
|
+
run(argv: string[]): Promise<CommandResult>;
|
|
71
|
+
}
|
|
72
|
+
export declare class CliCmuxClient implements CmuxClient {
|
|
73
|
+
private readonly runner;
|
|
74
|
+
private binary;
|
|
75
|
+
private versionError;
|
|
76
|
+
private identifyError;
|
|
77
|
+
private lastRunThrew;
|
|
78
|
+
private createError;
|
|
79
|
+
constructor(runner?: CommandRunner, binary?: string);
|
|
80
|
+
version(): Promise<string | null>;
|
|
81
|
+
getVersionError(): 'unavailable' | 'hard';
|
|
82
|
+
identify(): Promise<CmuxIdentity | null>;
|
|
83
|
+
getIdentifyError(): 'unavailable' | 'hard';
|
|
84
|
+
createSurface(input: {
|
|
85
|
+
workspaceId: string;
|
|
86
|
+
targetSurfaceId: string;
|
|
87
|
+
direction: 'right' | 'down';
|
|
88
|
+
focus: false;
|
|
89
|
+
}, socketPath?: string): Promise<{
|
|
90
|
+
paneId: string;
|
|
91
|
+
surfaceId: string;
|
|
92
|
+
} | null>;
|
|
93
|
+
getCreateError(): 'not_found' | 'unavailable' | 'invalid_state' | 'hard';
|
|
94
|
+
respawnSurface(workspaceId: string, surfaceId: string, command: string, socketPath?: string): Promise<boolean>;
|
|
95
|
+
closeSurface(workspaceId: string, surfaceId: string, socketPath?: string): Promise<'closed' | 'not_found' | 'failed'>;
|
|
96
|
+
equalizeSplits(params: {
|
|
97
|
+
workspace_id: string;
|
|
98
|
+
orientation: 'vertical';
|
|
99
|
+
}, socketPath?: string): Promise<boolean>;
|
|
100
|
+
private run;
|
|
101
|
+
}
|
|
102
|
+
export declare function resetCmuxStateForTests(): void;
|