opencode-synced 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.
@@ -0,0 +1,3 @@
1
+ import type { SyncPlan } from './paths.ts';
2
+ export declare function syncRepoToLocal(plan: SyncPlan, overrides: Record<string, unknown> | null): Promise<void>;
3
+ export declare function syncLocalToRepo(plan: SyncPlan, overrides: Record<string, unknown> | null): Promise<void>;
@@ -0,0 +1,9 @@
1
+ import type { PluginInput } from '@opencode-ai/plugin';
2
+ type CommitClient = PluginInput['client'];
3
+ type Shell = PluginInput['$'];
4
+ interface CommitContext {
5
+ client: CommitClient;
6
+ $: Shell;
7
+ }
8
+ export declare function generateCommitMessage(ctx: CommitContext, repoDir: string, fallbackDate?: Date): Promise<string>;
9
+ export {};
@@ -0,0 +1,35 @@
1
+ import type { SyncLocations } from './paths.ts';
2
+ export interface SyncRepoConfig {
3
+ url?: string;
4
+ owner?: string;
5
+ name?: string;
6
+ branch?: string;
7
+ }
8
+ export interface SyncConfig {
9
+ repo?: SyncRepoConfig;
10
+ localRepoPath?: string;
11
+ includeSecrets?: boolean;
12
+ includeSessions?: boolean;
13
+ includePromptStash?: boolean;
14
+ extraSecretPaths?: string[];
15
+ }
16
+ export interface SyncState {
17
+ lastPull?: string;
18
+ lastPush?: string;
19
+ lastRemoteUpdate?: string;
20
+ }
21
+ export declare function pathExists(filePath: string): Promise<boolean>;
22
+ export declare function normalizeSyncConfig(config: SyncConfig): SyncConfig;
23
+ export declare function loadSyncConfig(locations: SyncLocations): Promise<SyncConfig | null>;
24
+ export declare function writeSyncConfig(locations: SyncLocations, config: SyncConfig): Promise<void>;
25
+ export declare function loadOverrides(locations: SyncLocations): Promise<Record<string, unknown> | null>;
26
+ export declare function loadState(locations: SyncLocations): Promise<SyncState>;
27
+ export declare function writeState(locations: SyncLocations, state: SyncState): Promise<void>;
28
+ export declare function applyOverridesToRuntimeConfig(config: Record<string, unknown>, overrides: Record<string, unknown>): void;
29
+ export declare function deepMerge<T>(base: T, override: unknown): T;
30
+ export declare function stripOverrides(localConfig: Record<string, unknown>, overrides: Record<string, unknown>, baseConfig: Record<string, unknown> | null): Record<string, unknown>;
31
+ export declare function parseJsonc<T>(content: string): T;
32
+ export declare function writeJsonFile(filePath: string, data: unknown, options?: {
33
+ jsonc: boolean;
34
+ mode?: number;
35
+ }): Promise<void>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,19 @@
1
+ export declare class SyncError extends Error {
2
+ readonly code: string;
3
+ constructor(code: string, message: string);
4
+ }
5
+ export declare class SyncConfigMissingError extends SyncError {
6
+ constructor(message: string);
7
+ }
8
+ export declare class RepoDivergedError extends SyncError {
9
+ constructor(message: string);
10
+ }
11
+ export declare class RepoPrivateRequiredError extends SyncError {
12
+ constructor(message: string);
13
+ }
14
+ export declare class RepoVisibilityError extends SyncError {
15
+ constructor(message: string);
16
+ }
17
+ export declare class SyncCommandError extends SyncError {
18
+ constructor(message: string);
19
+ }
@@ -0,0 +1,47 @@
1
+ import type { SyncConfig } from './config.ts';
2
+ export interface XdgPaths {
3
+ homeDir: string;
4
+ configDir: string;
5
+ dataDir: string;
6
+ stateDir: string;
7
+ }
8
+ export interface SyncLocations {
9
+ xdg: XdgPaths;
10
+ configRoot: string;
11
+ syncConfigPath: string;
12
+ overridesPath: string;
13
+ statePath: string;
14
+ defaultRepoDir: string;
15
+ }
16
+ export type SyncItemType = 'file' | 'dir';
17
+ export interface SyncItem {
18
+ localPath: string;
19
+ repoPath: string;
20
+ type: SyncItemType;
21
+ isSecret: boolean;
22
+ isConfigFile: boolean;
23
+ }
24
+ export interface ExtraSecretPlan {
25
+ allowlist: string[];
26
+ manifestPath: string;
27
+ entries: Array<{
28
+ sourcePath: string;
29
+ repoPath: string;
30
+ }>;
31
+ }
32
+ export interface SyncPlan {
33
+ items: SyncItem[];
34
+ extraSecrets: ExtraSecretPlan;
35
+ repoRoot: string;
36
+ homeDir: string;
37
+ platform: NodeJS.Platform;
38
+ }
39
+ export declare function resolveHomeDir(env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform): string;
40
+ export declare function resolveXdgPaths(env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform): XdgPaths;
41
+ export declare function resolveSyncLocations(env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform): SyncLocations;
42
+ export declare function expandHome(inputPath: string, homeDir: string): string;
43
+ export declare function normalizePath(inputPath: string, homeDir: string, platform?: NodeJS.Platform): string;
44
+ export declare function isSamePath(left: string, right: string, homeDir: string, platform?: NodeJS.Platform): boolean;
45
+ export declare function encodeSecretPath(inputPath: string): string;
46
+ export declare function resolveRepoRoot(config: SyncConfig | null, locations: SyncLocations): string;
47
+ export declare function buildSyncPlan(config: SyncConfig, locations: SyncLocations, repoRoot: string, platform?: NodeJS.Platform): SyncPlan;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,25 @@
1
+ import type { PluginInput } from '@opencode-ai/plugin';
2
+ import type { SyncConfig } from './config.ts';
3
+ export interface RepoStatus {
4
+ branch: string;
5
+ changes: string[];
6
+ }
7
+ export interface RepoUpdateResult {
8
+ updated: boolean;
9
+ branch: string;
10
+ }
11
+ type Shell = PluginInput['$'];
12
+ export declare function isRepoCloned(repoDir: string): Promise<boolean>;
13
+ export declare function resolveRepoIdentifier(config: SyncConfig): string;
14
+ export declare function resolveRepoBranch(config: SyncConfig, fallback?: string): string;
15
+ export declare function ensureRepoCloned($: Shell, config: SyncConfig, repoDir: string): Promise<void>;
16
+ export declare function ensureRepoPrivate($: Shell, config: SyncConfig): Promise<void>;
17
+ export declare function parseRepoVisibility(output: string): boolean;
18
+ export declare function fetchAndFastForward($: Shell, repoDir: string, branch: string): Promise<RepoUpdateResult>;
19
+ export declare function getRepoStatus($: Shell, repoDir: string): Promise<RepoStatus>;
20
+ export declare function hasLocalChanges($: Shell, repoDir: string): Promise<boolean>;
21
+ export declare function commitAll($: Shell, repoDir: string, message: string): Promise<void>;
22
+ export declare function pushBranch($: Shell, repoDir: string, branch: string): Promise<void>;
23
+ export declare function repoExists($: Shell, repoIdentifier: string): Promise<boolean>;
24
+ export declare function getAuthenticatedUser($: Shell): Promise<string>;
25
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,27 @@
1
+ import type { PluginInput } from '@opencode-ai/plugin';
2
+ type SyncServiceContext = Pick<PluginInput, 'client' | '$'>;
3
+ interface InitOptions {
4
+ repo?: string;
5
+ owner?: string;
6
+ name?: string;
7
+ url?: string;
8
+ branch?: string;
9
+ includeSecrets?: boolean;
10
+ includeSessions?: boolean;
11
+ includePromptStash?: boolean;
12
+ create?: boolean;
13
+ private?: boolean;
14
+ extraSecretPaths?: string[];
15
+ localRepoPath?: string;
16
+ }
17
+ export interface SyncService {
18
+ startupSync: () => Promise<void>;
19
+ status: () => Promise<string>;
20
+ init: (_options: InitOptions) => Promise<string>;
21
+ pull: () => Promise<string>;
22
+ push: () => Promise<string>;
23
+ enableSecrets: (_extraSecretPaths?: string[]) => Promise<string>;
24
+ resolve: () => Promise<string>;
25
+ }
26
+ export declare function createSyncService(ctx: SyncServiceContext): SyncService;
27
+ export {};
@@ -0,0 +1,9 @@
1
+ import type { PluginInput } from '@opencode-ai/plugin';
2
+ type Client = PluginInput['client'];
3
+ export declare function unwrapData<T>(response: unknown): T | null;
4
+ export declare function extractTextFromResponse(response: unknown): string | null;
5
+ export declare function resolveSmallModel(client: Client): Promise<{
6
+ providerID: string;
7
+ modelID: string;
8
+ } | null>;
9
+ export {};
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "opencode-synced",
3
+ "version": "0.1.0",
4
+ "description": "Sync global OpenCode config across machines via GitHub.",
5
+ "author": {
6
+ "name": "Ian Hildebrand"
7
+ },
8
+ "type": "module",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "default": "./dist/index.js"
13
+ }
14
+ },
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/iHildy/opencode-synced.git"
18
+ },
19
+ "publishConfig": {
20
+ "access": "public"
21
+ },
22
+ "files": [
23
+ "dist"
24
+ ],
25
+ "dependencies": {
26
+ "@opencode-ai/plugin": "1.0.85"
27
+ },
28
+ "devDependencies": {
29
+ "@eslint/js": "^9.39.1",
30
+ "@types/node": "^20.11.5",
31
+ "@typescript-eslint/eslint-plugin": "8.47.0",
32
+ "@typescript-eslint/parser": "8.47.0",
33
+ "bun-types": "latest",
34
+ "eslint": "^9.39.1",
35
+ "eslint-config-prettier": "10.1.8",
36
+ "eslint-plugin-prettier": "^5.1.3",
37
+ "prettier": "^3.2.4",
38
+ "typescript": "^5.9.2",
39
+ "typescript-eslint": "^8.47.0",
40
+ "vitest": "^3.2.4"
41
+ },
42
+ "scripts": {
43
+ "build": "rm -rf dist && bun build ./src/index.ts --outdir dist --target bun && tsc -p tsconfig.build.json && cp -r src/command dist/command",
44
+ "test": "vitest run",
45
+ "test:watch": "vitest",
46
+ "lint": "eslint .",
47
+ "lint:fix": "eslint . --fix",
48
+ "format": "prettier --write ."
49
+ }
50
+ }