opencode-plugin-flow 4.3.1 → 4.3.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/CHANGELOG.md CHANGED
@@ -2,6 +2,51 @@
2
2
 
3
3
  One short entry per release, written for users deciding whether to upgrade.
4
4
 
5
+ ## [4.3.3] - 2026-07-07
6
+
7
+ Verification only — no behavior change:
8
+
9
+ - The live OpenCode smoke test now proves the hidden read-only workers'
10
+ isolation actually binds at runtime: against a real server it asserts each
11
+ worker's resolved permission rules deny the state-changing `flow_*` tools,
12
+ `task`, `skill`, and `edit`, while keeping `flow_status` readable. This
13
+ confirms OpenCode compiles Flow's tool-name and wildcard permission keys
14
+ (which are absent from the SDK's simplified permission type) rather than
15
+ silently dropping them, closing the one unverified question from the 4.3.2
16
+ review.
17
+
18
+ ## [4.3.2] - 2026-07-07
19
+
20
+ Correctness and safety hardening from a full-project review, repairing two
21
+ edges introduced in 4.3.1 and several older ones:
22
+
23
+ - Uninstall no longer deletes a user file that merely resembles a backup name:
24
+ a file counts as removable Flow residue only when its name and its content
25
+ checksum both match Flow's backup format. Doctor applies the same check.
26
+ - Sync no longer overwrites a user-owned skill folder that has files at managed
27
+ paths but no `SKILL.md` — any managed folder without a Flow marker is left
28
+ untouched, not clobbered without a backup.
29
+ - An empty `HOME` no longer makes the skills root a current-directory-relative
30
+ path (which sync wrote into and uninstall removed); it falls back to the OS
31
+ home. `engines` now requires Node `>=20.12` (doctor/uninstall rely on it).
32
+ - The CLI no longer aborts on a stray `flow-*` file in the skills root, and a
33
+ CRLF-converted skill marker is no longer misreported as outdated.
34
+ - Session locks recover from more failure modes: a far-future or foreign-host
35
+ lock timestamp and a recycled process id are now reclaimable instead of
36
+ wedging every Flow call, and stale-lock reclamation no longer races two
37
+ waiters into holding the lock at once.
38
+ - `flow_status` re-checks the session under the lock before quarantining, so a
39
+ session written by a concurrent process can't be quarantined by mistake; a
40
+ session file with an archive-unsafe id now routes to quarantine recovery
41
+ instead of wedging every archive; and its output is framed as data to blunt
42
+ instruction-injection from a cloned repo's session file.
43
+ - A user command named like an object built-in (e.g. `/toString`) no longer
44
+ crashes command preflight, and a Flow command invoked with an attachment now
45
+ keeps its worker isolated instead of double-running the instructions.
46
+ - Session history is bounded so long autonomous loops cannot grow the session
47
+ file without limit. Docs corrected to match the current uninstall/doctor
48
+ behavior.
49
+
5
50
  ## [4.3.1] - 2026-07-06
6
51
 
7
52
  Doctor and uninstall now account for the `.backup` files Flow writes when it
package/README.md CHANGED
@@ -17,8 +17,8 @@ Full project documentation is available in the
17
17
  ## Quick start
18
18
 
19
19
  ```bash
20
- opencode plugin opencode-plugin-flow@4.3.1 --global --force
21
- npx -y opencode-plugin-flow@4.3.1 sync
20
+ opencode plugin opencode-plugin-flow@4.3.3 --global --force
21
+ npx -y opencode-plugin-flow@4.3.3 sync
22
22
  ```
23
23
 
24
24
  Restart OpenCode, then give Flow a goal:
@@ -135,7 +135,7 @@ To update a pinned Flow version, rerun the install command with the new
135
135
  version. To inspect skill health:
136
136
 
137
137
  ```bash
138
- npx -y opencode-plugin-flow@4.3.1 doctor
138
+ npx -y opencode-plugin-flow@4.3.3 doctor
139
139
  ```
140
140
 
141
141
  ## Experimental: compaction context
package/dist/cli.js CHANGED
@@ -1789,12 +1789,34 @@ var FLOW_SKILL_DEFINITIONS = [
1789
1789
 
1790
1790
  // src/distribution/sync.ts
1791
1791
  var MARKER_FILENAME = ".flow-skill-version";
1792
- var BACKUP_FILE_PATTERN = /\.backup\.[0-9a-f]{12}(?:\.\d+)?$/;
1793
- function isFlowBackupFile(relativePath) {
1794
- return BACKUP_FILE_PATTERN.test(relativePath);
1792
+ var BACKUP_FILE_PATTERN = /\.backup\.([0-9a-f]{12})(?:\.\d+)?$/;
1793
+ function backupHashFromName(relativePath) {
1794
+ return BACKUP_FILE_PATTERN.exec(relativePath)?.[1] ?? null;
1795
+ }
1796
+ async function isFlowCreatedBackup(folder, relativePath) {
1797
+ const namedHash = backupHashFromName(relativePath);
1798
+ if (!namedHash)
1799
+ return false;
1800
+ const content = await optionalRead(resolveSkillFile(folder, relativePath));
1801
+ if (content === null)
1802
+ return false;
1803
+ return sha256(content).slice(0, 12) === namedHash;
1804
+ }
1805
+ function normalizeNewlines(value) {
1806
+ return value.replace(/\r\n/g, `
1807
+ `);
1808
+ }
1809
+ var CHANGED_SYNC_ACTIONS = [
1810
+ "installed",
1811
+ "updated",
1812
+ "updated_with_backup"
1813
+ ];
1814
+ function isChangedSyncAction(action) {
1815
+ return CHANGED_SYNC_ACTIONS.includes(action);
1795
1816
  }
1796
1817
  function homeDir() {
1797
- return process.env.HOME ?? process.env.USERPROFILE ?? homedir();
1818
+ const configured = process.env.HOME?.trim() || process.env.USERPROFILE?.trim();
1819
+ return configured || homedir();
1798
1820
  }
1799
1821
  function resolveFlowSkillsRoot(home = homeDir()) {
1800
1822
  return join(home, ".config", "opencode", "skills");
@@ -1814,7 +1836,8 @@ async function optionalRead(path) {
1814
1836
  try {
1815
1837
  return await readFile(path, "utf8");
1816
1838
  } catch (error) {
1817
- if (error.code === "ENOENT")
1839
+ const code = error.code;
1840
+ if (code === "ENOENT" || code === "ENOTDIR")
1818
1841
  return null;
1819
1842
  throw error;
1820
1843
  }
@@ -1870,9 +1893,13 @@ async function syncSkill(definition, version, root) {
1870
1893
  const markerPath = join(folder, MARKER_FILENAME);
1871
1894
  const markerContent = await optionalRead(markerPath);
1872
1895
  const existingMarkerHashes = parseMarkerFiles(markerContent);
1873
- const existingSkill = await optionalRead(join(folder, "SKILL.md"));
1874
- if (existingSkill !== null && markerContent === null) {
1875
- return { name: definition.name, action: "skipped_foreign" };
1896
+ if (markerContent === null) {
1897
+ for (const file of definition.files) {
1898
+ const existing = await optionalRead(resolveSkillFile(folder, file.relativePath));
1899
+ if (existing !== null) {
1900
+ return { name: definition.name, action: "skipped_foreign" };
1901
+ }
1902
+ }
1876
1903
  }
1877
1904
  let changed = false;
1878
1905
  const backupPaths = [];
@@ -1902,7 +1929,7 @@ async function syncSkill(definition, version, root) {
1902
1929
  }
1903
1930
  await rm(path, { force: true });
1904
1931
  }
1905
- if (!changed && markerContent === markerFor(definition, version)) {
1932
+ if (!changed && markerContent !== null && normalizeNewlines(markerContent) === markerFor(definition, version)) {
1906
1933
  return { name: definition.name, action: "unchanged" };
1907
1934
  }
1908
1935
  if (!changed) {
@@ -2000,7 +2027,7 @@ async function inspectFlowSkillInstall(version = resolveFlowPluginVersion(), hom
2000
2027
  }
2001
2028
  outdatedFiles.push(file.relativePath);
2002
2029
  }
2003
- const markerDrift = markerContent !== markerFor(definition, version);
2030
+ const markerDrift = normalizeNewlines(markerContent) !== markerFor(definition, version);
2004
2031
  const status = missingFiles.length > 0 ? "incomplete" : editedFiles.length > 0 ? "edited" : markerDrift || outdatedFiles.length > 0 ? "outdated" : "ok";
2005
2032
  return {
2006
2033
  name: definition.name,
@@ -2080,7 +2107,7 @@ function formatFlowSkillDoctor(report) {
2080
2107
  } else {
2081
2108
  lines.push("- Resolve user-owned or edited managed skill folders, then restart OpenCode. Move a folder aside to let Flow recreate it, or keep it intentionally as a local override.");
2082
2109
  if (report.skills.some((skill) => skill.backupFiles.length > 0)) {
2083
- lines.push("- Flow saved earlier local edits as .backup files; review each one and delete it once the saved copy is no longer needed. Sync ignores them, and they block a clean uninstall until removed.");
2110
+ lines.push("- Flow saved earlier local edits as .backup files; review each one and delete it once the saved copy is no longer needed. Sync ignores them, and uninstall removes them (naming each) along with the folder.");
2084
2111
  }
2085
2112
  }
2086
2113
  lines.push(`- Details command: ${formatFlowDoctorCommand(report.version)}`);
@@ -2096,13 +2123,20 @@ async function listSkillFolderFiles(folder) {
2096
2123
  return entries.filter((entry) => entry.isFile()).map((entry) => join(entry.parentPath, entry.name).slice(folder.length + 1).split(sep).join("/"));
2097
2124
  }
2098
2125
  async function listFlowBackupFiles(folder) {
2126
+ let names;
2099
2127
  try {
2100
- return (await listSkillFolderFiles(folder)).filter(isFlowBackupFile);
2128
+ names = await listSkillFolderFiles(folder);
2101
2129
  } catch (error) {
2102
2130
  if (error.code === "ENOENT")
2103
2131
  return [];
2104
2132
  throw error;
2105
2133
  }
2134
+ const backups = [];
2135
+ for (const name of names) {
2136
+ if (await isFlowCreatedBackup(folder, name))
2137
+ backups.push(name);
2138
+ }
2139
+ return backups;
2106
2140
  }
2107
2141
  async function inspectManagedFolderForUninstall(folder, markerContent) {
2108
2142
  const hashes = parseMarkerFiles(markerContent);
@@ -2112,17 +2146,19 @@ async function inspectManagedFolderForUninstall(folder, markerContent) {
2112
2146
  for (const relativePath of await listSkillFolderFiles(folder)) {
2113
2147
  if (relativePath === MARKER_FILENAME)
2114
2148
  continue;
2115
- if (isFlowBackupFile(relativePath)) {
2116
- backups.push(relativePath);
2149
+ const recordedHash = hashes.get(relativePath);
2150
+ if (recordedHash !== undefined) {
2151
+ const content = await optionalRead(resolveSkillFile(folder, relativePath));
2152
+ if (content === null || sha256(content) !== recordedHash) {
2153
+ return { pristine: false, backups };
2154
+ }
2117
2155
  continue;
2118
2156
  }
2119
- const recordedHash = hashes.get(relativePath);
2120
- if (recordedHash === undefined)
2121
- return { pristine: false, backups };
2122
- const content = await optionalRead(resolveSkillFile(folder, relativePath));
2123
- if (content === null || sha256(content) !== recordedHash) {
2124
- return { pristine: false, backups };
2157
+ if (await isFlowCreatedBackup(folder, relativePath)) {
2158
+ backups.push(relativePath);
2159
+ continue;
2125
2160
  }
2161
+ return { pristine: false, backups };
2126
2162
  }
2127
2163
  return { pristine: true, backups };
2128
2164
  }
@@ -2249,7 +2285,7 @@ async function main(argv) {
2249
2285
  if (command === "sync") {
2250
2286
  const version = resolveFlowPluginVersion();
2251
2287
  const results = await syncFlowSkills(version);
2252
- const changed = results.filter((result2) => ["installed", "updated", "updated_with_backup"].includes(result2.action));
2288
+ const changed = results.filter((result2) => isChangedSyncAction(result2.action));
2253
2289
  const actionRequired = results.filter((result2) => result2.action === "skipped_foreign");
2254
2290
  process.stdout.write(`Flow skill sync (${version})
2255
2291
  `);
@@ -2299,4 +2335,4 @@ main(process.argv).catch((error) => {
2299
2335
  process.exitCode = 1;
2300
2336
  });
2301
2337
 
2302
- //# debugId=056C129404DFA30D64756E2164756E21
2338
+ //# debugId=B10F4D7F094C050864756E2164756E21
package/dist/cli.js.map CHANGED
@@ -2,11 +2,11 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/distribution/sync.ts", "../src/distribution/flow-skill-definitions.ts", "../src/cli.ts"],
4
4
  "sourcesContent": [
5
- "import { createHash } from \"node:crypto\";\nimport { mkdir, readdir, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { homedir } from \"node:os\";\nimport { dirname, join, normalize, sep } from \"node:path\";\nimport {\n\tFLOW_SKILL_DEFINITIONS,\n\ttype FlowSkillDefinition,\n} from \"./flow-skill-definitions\";\n\nconst MARKER_FILENAME = \".flow-skill-version\";\n\n// Matches the `<file>.backup.<12 hex>` names writeBackup creates, plus its\n// `.N` collision suffix. These files hold the user's earlier local edits.\nconst BACKUP_FILE_PATTERN = /\\.backup\\.[0-9a-f]{12}(?:\\.\\d+)?$/;\n\nfunction isFlowBackupFile(relativePath: string): boolean {\n\treturn BACKUP_FILE_PATTERN.test(relativePath);\n}\n\ntype FlowLog = (level: \"info\" | \"warn\" | \"error\", message: string) => void;\n\nexport type FlowSkillSyncAction =\n\t| \"installed\"\n\t| \"updated\"\n\t| \"updated_with_backup\"\n\t| \"marker_updated\"\n\t| \"unchanged\"\n\t| \"skipped_foreign\";\n\nexport type FlowSkillSyncResult = {\n\tname: string;\n\taction: FlowSkillSyncAction;\n\tbackupPaths?: string[];\n};\n\nexport type FlowSkillSyncHealth = {\n\tstatus: \"ok\" | \"restart_required\" | \"action_required\" | \"error\";\n\tversion: string;\n\troot: string;\n\tcheckedAt: string;\n\texpectedSkills: string[];\n\tresults: FlowSkillSyncResult[];\n\tchangedSkills: string[];\n\tactionRequiredSkills: string[];\n\trestartRequired: boolean;\n\tsummary: string;\n\terror?: string;\n};\n\nexport type FlowSkillSetupStatus = {\n\tstatus: \"restart_required\" | \"action_required\" | \"sync_failed\";\n\tsummary: string;\n\tversion: string;\n\troot: string;\n\tchanged?: string[];\n\tactionRequired?: string[];\n\terror?: string;\n};\n\nexport type FlowSkillDoctorSkill = {\n\tname: string;\n\tpath: string;\n\tstatus: \"ok\" | \"missing\" | \"foreign\" | \"incomplete\" | \"edited\" | \"outdated\";\n\tmarkerVersion: string | null;\n\tmissingFiles: string[];\n\teditedFiles: string[];\n\toutdatedFiles: string[];\n\tbackupFiles: string[];\n};\n\nexport type FlowSkillDoctorReport = {\n\tstatus: \"ok\" | \"sync_required\" | \"action_required\";\n\tversion: string;\n\troot: string;\n\texpectedSkills: string[];\n\tskills: FlowSkillDoctorSkill[];\n\tsyncRequiredSkills: string[];\n\tactionRequiredSkills: string[];\n\tunmanagedFlowSkills: string[];\n};\n\nlet latestFlowSkillSyncHealth: FlowSkillSyncHealth | null = null;\n\nfunction homeDir(): string {\n\treturn process.env.HOME ?? process.env.USERPROFILE ?? homedir();\n}\n\nexport function resolveFlowSkillsRoot(home = homeDir()): string {\n\treturn join(home, \".config\", \"opencode\", \"skills\");\n}\n\nfunction sha256(value: string): string {\n\treturn createHash(\"sha256\").update(value).digest(\"hex\");\n}\n\nfunction markerFor(definition: FlowSkillDefinition, version: string): string {\n\treturn [\n\t\t`version=${version}`,\n\t\t...definition.files.map(\n\t\t\t(file) => `file=${file.relativePath} sha256=${sha256(file.content)}`,\n\t\t),\n\t\t\"\",\n\t].join(\"\\n\");\n}\n\nasync function optionalRead(path: string): Promise<string | null> {\n\ttry {\n\t\treturn await readFile(path, \"utf8\");\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code === \"ENOENT\") return null;\n\t\tthrow error;\n\t}\n}\n\nfunction parseMarkerFiles(content: string | null): Map<string, string> {\n\tconst files = new Map<string, string>();\n\tif (!content) return files;\n\tfor (const line of content.split(/\\r?\\n/)) {\n\t\tconst match =\n\t\t\t/^file=(.+) sha256=([a-f0-9]{64})$/.exec(line) ??\n\t\t\t/^file=(.+)=sha256:([a-f0-9]{64})$/.exec(line);\n\t\tif (match?.[1] && match[2]) files.set(match[1], match[2]);\n\t\tconst topLevelHash = /^hash=sha256:([a-f0-9]{64})$/.exec(line);\n\t\tif (topLevelHash?.[1] && !files.has(\"SKILL.md\")) {\n\t\t\tfiles.set(\"SKILL.md\", topLevelHash[1]);\n\t\t}\n\t}\n\treturn files;\n}\n\nfunction parseMarkerVersion(content: string | null): string | null {\n\tif (!content) return null;\n\tfor (const line of content.split(/\\r?\\n/)) {\n\t\tconst match = /^version=(.+)$/.exec(line);\n\t\tif (match?.[1]) return match[1];\n\t}\n\treturn null;\n}\n\nfunction resolveSkillFile(folder: string, relativePath: string): string {\n\tconst resolved = normalize(join(folder, ...relativePath.split(\"/\")));\n\tif (resolved !== folder && resolved.startsWith(`${folder}${sep}`)) {\n\t\treturn resolved;\n\t}\n\tthrow new Error(`Unsafe skill file path '${relativePath}'.`);\n}\n\nasync function writeBackup(path: string, content: string): Promise<string> {\n\tconst basePath = `${path}.backup.${sha256(content).slice(0, 12)}`;\n\tfor (let index = 0; ; index += 1) {\n\t\tconst backupPath = index === 0 ? basePath : `${basePath}.${index}`;\n\t\ttry {\n\t\t\tawait writeFile(backupPath, content, { encoding: \"utf8\", flag: \"wx\" });\n\t\t\treturn backupPath;\n\t\t} catch (error) {\n\t\t\tif ((error as NodeJS.ErrnoException).code === \"EEXIST\") continue;\n\t\t\tthrow error;\n\t\t}\n\t}\n}\n\nasync function syncSkill(\n\tdefinition: FlowSkillDefinition,\n\tversion: string,\n\troot: string,\n): Promise<FlowSkillSyncResult> {\n\tconst folder = join(root, definition.name);\n\tconst markerPath = join(folder, MARKER_FILENAME);\n\tconst markerContent = await optionalRead(markerPath);\n\tconst existingMarkerHashes = parseMarkerFiles(markerContent);\n\tconst existingSkill = await optionalRead(join(folder, \"SKILL.md\"));\n\tif (existingSkill !== null && markerContent === null) {\n\t\treturn { name: definition.name, action: \"skipped_foreign\" as const };\n\t}\n\n\tlet changed = false;\n\tconst backupPaths: string[] = [];\n\tconst currentRelativePaths = new Set(\n\t\tdefinition.files.map((file) => file.relativePath),\n\t);\n\tfor (const file of definition.files) {\n\t\tconst path = resolveSkillFile(folder, file.relativePath);\n\t\tconst existing = await optionalRead(path);\n\t\tif (existing === file.content) continue;\n\t\tchanged = true;\n\t\tconst recordedHash = existingMarkerHashes.get(file.relativePath);\n\t\tconst userEdited =\n\t\t\texisting !== null &&\n\t\t\t(recordedHash\n\t\t\t\t? sha256(existing) !== recordedHash\n\t\t\t\t: markerContent !== null);\n\t\tif (userEdited) {\n\t\t\tbackupPaths.push(await writeBackup(path, existing));\n\t\t}\n\t}\n\tfor (const [relativePath, recordedHash] of existingMarkerHashes) {\n\t\tif (currentRelativePaths.has(relativePath)) continue;\n\t\tconst path = resolveSkillFile(folder, relativePath);\n\t\tconst existing = await optionalRead(path);\n\t\tif (existing === null) continue;\n\t\tchanged = true;\n\t\tif (sha256(existing) !== recordedHash) {\n\t\t\tbackupPaths.push(await writeBackup(path, existing));\n\t\t}\n\t\tawait rm(path, { force: true });\n\t}\n\n\tif (!changed && markerContent === markerFor(definition, version)) {\n\t\treturn { name: definition.name, action: \"unchanged\" };\n\t}\n\n\tif (!changed) {\n\t\tawait writeFile(markerPath, markerFor(definition, version), \"utf8\");\n\t\treturn { name: definition.name, action: \"marker_updated\" };\n\t}\n\n\tconst managedSkillExists = markerContent !== null;\n\tfor (const file of definition.files) {\n\t\tconst path = resolveSkillFile(folder, file.relativePath);\n\t\tawait mkdir(dirname(path), { recursive: true });\n\t\tawait writeFile(path, file.content, \"utf8\");\n\t}\n\tawait writeFile(markerPath, markerFor(definition, version), \"utf8\");\n\treturn {\n\t\tname: definition.name,\n\t\taction:\n\t\t\tbackupPaths.length > 0\n\t\t\t\t? \"updated_with_backup\"\n\t\t\t\t: managedSkillExists\n\t\t\t\t\t? \"updated\"\n\t\t\t\t\t: \"installed\",\n\t\t...(backupPaths.length > 0 ? { backupPaths } : {}),\n\t};\n}\n\nfunction expectedSkillNames(): string[] {\n\treturn FLOW_SKILL_DEFINITIONS.map((definition) => definition.name);\n}\n\nfunction createHealth(\n\tversion: string,\n\troot: string,\n\tresults: FlowSkillSyncResult[],\n): FlowSkillSyncHealth {\n\tconst changedSkills = results\n\t\t.filter((result) =>\n\t\t\t[\"installed\", \"updated\", \"updated_with_backup\"].includes(result.action),\n\t\t)\n\t\t.map((result) => result.name);\n\tconst actionRequiredSkills = results\n\t\t.filter((result) => result.action === \"skipped_foreign\")\n\t\t.map((result) => result.name);\n\tconst status =\n\t\tactionRequiredSkills.length > 0\n\t\t\t? \"action_required\"\n\t\t\t: changedSkills.length > 0\n\t\t\t\t? \"restart_required\"\n\t\t\t\t: \"ok\";\n\tconst summaryParts: string[] = [];\n\tif (changedSkills.length > 0) {\n\t\tsummaryParts.push(\n\t\t\t`Flow installed or updated skills during this startup (${changedSkills.join(\", \")}). Restart OpenCode before loading Flow skills.`,\n\t\t);\n\t}\n\tif (actionRequiredSkills.length > 0) {\n\t\tsummaryParts.push(\n\t\t\t`Flow found user-owned skill folders for managed skills (${actionRequiredSkills.join(\", \")}). Run ${formatFlowDoctorCommand(version)} for repair guidance.`,\n\t\t);\n\t}\n\tconst summary =\n\t\tsummaryParts.length > 0\n\t\t\t? summaryParts.join(\" \")\n\t\t\t: \"Flow skills are synced.\";\n\treturn {\n\t\tstatus,\n\t\tversion,\n\t\troot,\n\t\tcheckedAt: new Date().toISOString(),\n\t\texpectedSkills: expectedSkillNames(),\n\t\tresults,\n\t\tchangedSkills,\n\t\tactionRequiredSkills,\n\t\trestartRequired: changedSkills.length > 0,\n\t\tsummary,\n\t};\n}\n\nfunction createErrorHealth(\n\tversion: string,\n\troot: string,\n\terror: unknown,\n): FlowSkillSyncHealth {\n\tconst message = error instanceof Error ? error.message : String(error);\n\treturn {\n\t\tstatus: \"error\",\n\t\tversion,\n\t\troot,\n\t\tcheckedAt: new Date().toISOString(),\n\t\texpectedSkills: expectedSkillNames(),\n\t\tresults: [],\n\t\tchangedSkills: [],\n\t\tactionRequiredSkills: [],\n\t\trestartRequired: false,\n\t\tsummary: `Flow skill sync failed: ${message}`,\n\t\terror: message,\n\t};\n}\n\nexport function getLatestFlowSkillSyncHealth(): FlowSkillSyncHealth | null {\n\treturn latestFlowSkillSyncHealth;\n}\n\nexport function formatFlowDoctorCommand(version: string): string {\n\tconst pin = version === \"0.0.0\" ? \"latest\" : version;\n\treturn `npx -y opencode-plugin-flow@${pin} doctor`;\n}\n\nexport function getFlowSkillSetupStatus(\n\thealth = latestFlowSkillSyncHealth,\n): FlowSkillSetupStatus | null {\n\tif (!health || health.status === \"ok\") return null;\n\tconst status = health.status === \"error\" ? \"sync_failed\" : health.status;\n\treturn {\n\t\tstatus,\n\t\tsummary: health.summary,\n\t\tversion: health.version,\n\t\troot: health.root,\n\t\t...(health.changedSkills.length > 0\n\t\t\t? { changed: health.changedSkills }\n\t\t\t: {}),\n\t\t...(health.actionRequiredSkills.length > 0\n\t\t\t? { actionRequired: health.actionRequiredSkills }\n\t\t\t: {}),\n\t\t...(health.error ? { error: health.error } : {}),\n\t};\n}\n\nexport function formatFlowSkillSetupWarning(\n\thealth = latestFlowSkillSyncHealth,\n): string | null {\n\tconst setup = getFlowSkillSetupStatus(health);\n\tif (!setup) return null;\n\treturn [\n\t\t\"Flow setup warning:\",\n\t\tsetup.summary,\n\t\t`Skills root: ${setup.root}`,\n\t\t`Use \\`${formatFlowDoctorCommand(setup.version)}\\` for details.`,\n\t].join(\"\\n\");\n}\n\nexport function resolveFlowPluginVersion(): string {\n\tif (process.env.npm_package_version) return process.env.npm_package_version;\n\ttry {\n\t\tconst require = createRequire(import.meta.url);\n\t\tfor (const path of [\"../package.json\", \"../../package.json\"]) {\n\t\t\ttry {\n\t\t\t\tconst manifest = require(path) as { version?: string };\n\t\t\t\tif (manifest.version) return manifest.version;\n\t\t\t} catch {\n\t\t\t\t// Try the next layout: source tree and bundled dist differ.\n\t\t\t}\n\t\t}\n\t} catch {\n\t\t// Fall through to sentinel.\n\t}\n\treturn \"0.0.0\";\n}\n\nexport async function syncFlowSkills(version: string, home = homeDir()) {\n\tconst root = resolveFlowSkillsRoot(home);\n\treturn Promise.all(\n\t\tFLOW_SKILL_DEFINITIONS.map((definition) =>\n\t\t\tsyncSkill(definition, version, root),\n\t\t),\n\t);\n}\n\nexport async function runFlowSkillSync(\n\tversion: string,\n\tlog: FlowLog,\n\thome = homeDir(),\n): Promise<void> {\n\tconst root = resolveFlowSkillsRoot(home);\n\ttry {\n\t\tconst results = await syncFlowSkills(version, home);\n\t\tlatestFlowSkillSyncHealth = createHealth(version, root, results);\n\t\tconst changed = results.filter(\n\t\t\t(result) =>\n\t\t\t\tresult.action === \"installed\" ||\n\t\t\t\tresult.action === \"updated\" ||\n\t\t\t\tresult.action === \"updated_with_backup\",\n\t\t);\n\t\tif (changed.length > 0) {\n\t\t\tlog(\n\t\t\t\t\"info\",\n\t\t\t\t`Flow synced skills (${changed.map((item) => `${item.name}:${item.action}`).join(\", \")}). Restart OpenCode if skills were just installed.`,\n\t\t\t);\n\t\t}\n\t\tif (latestFlowSkillSyncHealth.status === \"action_required\") {\n\t\t\tlog(\"warn\", latestFlowSkillSyncHealth.summary);\n\t\t}\n\t} catch (error) {\n\t\tlatestFlowSkillSyncHealth = createErrorHealth(version, root, error);\n\t\tlog(\"warn\", latestFlowSkillSyncHealth.summary);\n\t}\n}\n\nexport async function inspectFlowSkillInstall(\n\tversion = resolveFlowPluginVersion(),\n\thome = homeDir(),\n): Promise<FlowSkillDoctorReport> {\n\tconst root = resolveFlowSkillsRoot(home);\n\tconst expected = new Set(expectedSkillNames());\n\tconst skills = await Promise.all(\n\t\tFLOW_SKILL_DEFINITIONS.map(async (definition) => {\n\t\t\tconst folder = join(root, definition.name);\n\t\t\tconst markerContent = await optionalRead(join(folder, MARKER_FILENAME));\n\t\t\tconst markerVersion = parseMarkerVersion(markerContent);\n\t\t\tconst markerHashes = parseMarkerFiles(markerContent);\n\t\t\tconst existingSkill = await optionalRead(join(folder, \"SKILL.md\"));\n\t\t\tconst backupFiles =\n\t\t\t\tmarkerContent === null ? [] : await listFlowBackupFiles(folder);\n\t\t\tif (existingSkill === null) {\n\t\t\t\treturn {\n\t\t\t\t\tname: definition.name,\n\t\t\t\t\tpath: folder,\n\t\t\t\t\tstatus: \"missing\" as const,\n\t\t\t\t\tmarkerVersion,\n\t\t\t\t\tmissingFiles: definition.files.map((file) => file.relativePath),\n\t\t\t\t\teditedFiles: [],\n\t\t\t\t\toutdatedFiles: [],\n\t\t\t\t\tbackupFiles,\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (markerContent === null) {\n\t\t\t\treturn {\n\t\t\t\t\tname: definition.name,\n\t\t\t\t\tpath: folder,\n\t\t\t\t\tstatus: \"foreign\" as const,\n\t\t\t\t\tmarkerVersion,\n\t\t\t\t\tmissingFiles: [],\n\t\t\t\t\teditedFiles: [],\n\t\t\t\t\toutdatedFiles: [],\n\t\t\t\t\tbackupFiles,\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst missingFiles: string[] = [];\n\t\t\tconst editedFiles: string[] = [];\n\t\t\tconst outdatedFiles: string[] = [];\n\t\t\tfor (const file of definition.files) {\n\t\t\t\tconst existing = await optionalRead(\n\t\t\t\t\tresolveSkillFile(folder, file.relativePath),\n\t\t\t\t);\n\t\t\t\tif (existing === null) {\n\t\t\t\t\tmissingFiles.push(file.relativePath);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (existing === file.content) continue;\n\t\t\t\tconst recordedHash = markerHashes.get(file.relativePath);\n\t\t\t\tif (recordedHash && sha256(existing) !== recordedHash) {\n\t\t\t\t\teditedFiles.push(file.relativePath);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\toutdatedFiles.push(file.relativePath);\n\t\t\t}\n\t\t\tconst markerDrift = markerContent !== markerFor(definition, version);\n\t\t\tconst status: FlowSkillDoctorSkill[\"status\"] =\n\t\t\t\tmissingFiles.length > 0\n\t\t\t\t\t? \"incomplete\"\n\t\t\t\t\t: editedFiles.length > 0\n\t\t\t\t\t\t? \"edited\"\n\t\t\t\t\t\t: markerDrift || outdatedFiles.length > 0\n\t\t\t\t\t\t\t? \"outdated\"\n\t\t\t\t\t\t\t: \"ok\";\n\t\t\treturn {\n\t\t\t\tname: definition.name,\n\t\t\t\tpath: folder,\n\t\t\t\tstatus,\n\t\t\t\tmarkerVersion,\n\t\t\t\tmissingFiles,\n\t\t\t\teditedFiles,\n\t\t\t\toutdatedFiles,\n\t\t\t\tbackupFiles,\n\t\t\t};\n\t\t}),\n\t);\n\n\tlet entries: string[] = [];\n\ttry {\n\t\tentries = await readdir(root);\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n\t}\n\tconst unmanagedFlowSkills = entries\n\t\t.filter(\n\t\t\t(name) =>\n\t\t\t\t(name === \"flow\" || name.startsWith(\"flow-\")) && !expected.has(name),\n\t\t)\n\t\t.map((name) => join(root, name));\n\n\tconst syncRequiredSkills = skills\n\t\t.filter((skill) =>\n\t\t\t[\"missing\", \"incomplete\", \"outdated\"].includes(skill.status),\n\t\t)\n\t\t.map((skill) => skill.name);\n\tconst actionRequiredSkills = skills\n\t\t.filter(\n\t\t\t(skill) =>\n\t\t\t\t[\"foreign\", \"edited\"].includes(skill.status) ||\n\t\t\t\tskill.backupFiles.length > 0,\n\t\t)\n\t\t.map((skill) => skill.name);\n\tconst actionRequired = actionRequiredSkills.length > 0;\n\tconst syncRequired = syncRequiredSkills.length > 0;\n\treturn {\n\t\tstatus: actionRequired\n\t\t\t? \"action_required\"\n\t\t\t: syncRequired\n\t\t\t\t? \"sync_required\"\n\t\t\t\t: \"ok\",\n\t\tversion,\n\t\troot,\n\t\texpectedSkills: [...expected],\n\t\tskills,\n\t\tsyncRequiredSkills,\n\t\tactionRequiredSkills,\n\t\tunmanagedFlowSkills,\n\t};\n}\n\nfunction appendSkillList(\n\tlines: string[],\n\tlabel: string,\n\tskills: string[],\n): void {\n\tif (skills.length === 0) return;\n\tlines.push(`- ${label}: ${skills.join(\", \")}`);\n}\n\nexport function formatFlowSkillDoctor(report: FlowSkillDoctorReport): string {\n\tconst lines = [\n\t\t\"Flow doctor\",\n\t\t`- status: ${report.status}`,\n\t\t`- plugin version: ${report.version}`,\n\t\t`- skills root: ${report.root}`,\n\t\t`- expected skills: ${report.expectedSkills.join(\", \")}`,\n\t];\n\tappendSkillList(\n\t\tlines,\n\t\t\"startup sync can install/update\",\n\t\treport.syncRequiredSkills,\n\t);\n\tappendSkillList(lines, \"needs user decision\", report.actionRequiredSkills);\n\tlines.push(\"\", \"Skills:\");\n\tfor (const skill of report.skills) {\n\t\tlines.push(\n\t\t\t`- ${skill.name}: ${skill.status} (${skill.path})${\n\t\t\t\tskill.markerVersion ? ` marker=${skill.markerVersion}` : \"\"\n\t\t\t}`,\n\t\t);\n\t\tif (skill.missingFiles.length > 0) {\n\t\t\tlines.push(` missing: ${skill.missingFiles.join(\", \")}`);\n\t\t}\n\t\tif (skill.editedFiles.length > 0) {\n\t\t\tlines.push(` edited: ${skill.editedFiles.join(\", \")}`);\n\t\t}\n\t\tif (skill.outdatedFiles.length > 0) {\n\t\t\tlines.push(` outdated: ${skill.outdatedFiles.join(\", \")}`);\n\t\t}\n\t\tif (skill.backupFiles.length > 0) {\n\t\t\tlines.push(` backups: ${skill.backupFiles.join(\", \")}`);\n\t\t}\n\t}\n\tif (report.unmanagedFlowSkills.length > 0) {\n\t\tlines.push(\"\", \"Unmanaged Flow-like skill folders:\");\n\t\tfor (const path of report.unmanagedFlowSkills) lines.push(`- ${path}`);\n\t}\n\tlines.push(\"\", \"Recommendation:\");\n\tif (report.status === \"ok\") {\n\t\tlines.push(\"- Flow skills are present and current.\");\n\t} else if (report.status === \"sync_required\") {\n\t\tlines.push(\n\t\t\t\"- Start or restart OpenCode with opencode-plugin-flow enabled so startup sync can install or update the listed skills. If Flow then reports restart_required, restart OpenCode once more so the refreshed skill registry is used.\",\n\t\t);\n\t} else {\n\t\tlines.push(\n\t\t\t\"- Resolve user-owned or edited managed skill folders, then restart OpenCode. Move a folder aside to let Flow recreate it, or keep it intentionally as a local override.\",\n\t\t);\n\t\tif (report.skills.some((skill) => skill.backupFiles.length > 0)) {\n\t\t\tlines.push(\n\t\t\t\t\"- Flow saved earlier local edits as .backup files; review each one and delete it once the saved copy is no longer needed. Sync ignores them, and they block a clean uninstall until removed.\",\n\t\t\t);\n\t\t}\n\t}\n\tlines.push(`- Details command: ${formatFlowDoctorCommand(report.version)}`);\n\treturn `${lines.join(\"\\n\")}\\n`;\n}\n\nasync function listSkillFolderFiles(folder: string): Promise<string[]> {\n\tconst entries = await readdir(folder, {\n\t\trecursive: true,\n\t\twithFileTypes: true,\n\t});\n\treturn entries\n\t\t.filter((entry) => entry.isFile())\n\t\t.map((entry) =>\n\t\t\tjoin(entry.parentPath, entry.name)\n\t\t\t\t.slice(folder.length + 1)\n\t\t\t\t.split(sep)\n\t\t\t\t.join(\"/\"),\n\t\t);\n}\n\nasync function listFlowBackupFiles(folder: string): Promise<string[]> {\n\ttry {\n\t\treturn (await listSkillFolderFiles(folder)).filter(isFlowBackupFile);\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code === \"ENOENT\") return [];\n\t\tthrow error;\n\t}\n}\n\n// A managed folder is removable when every non-marker file is either a pristine\n// managed file or Flow-created `.backup` residue. Backups hold the user's own\n// earlier edits, so they are returned separately: removable, but reported so the\n// deletion is never silent.\nasync function inspectManagedFolderForUninstall(\n\tfolder: string,\n\tmarkerContent: string,\n): Promise<{ pristine: boolean; backups: string[] }> {\n\tconst hashes = parseMarkerFiles(markerContent);\n\tif (hashes.size === 0) return { pristine: false, backups: [] };\n\tconst backups: string[] = [];\n\tfor (const relativePath of await listSkillFolderFiles(folder)) {\n\t\tif (relativePath === MARKER_FILENAME) continue;\n\t\tif (isFlowBackupFile(relativePath)) {\n\t\t\tbackups.push(relativePath);\n\t\t\tcontinue;\n\t\t}\n\t\tconst recordedHash = hashes.get(relativePath);\n\t\tif (recordedHash === undefined) return { pristine: false, backups };\n\t\tconst content = await optionalRead(resolveSkillFile(folder, relativePath));\n\t\tif (content === null || sha256(content) !== recordedHash) {\n\t\t\treturn { pristine: false, backups };\n\t\t}\n\t}\n\treturn { pristine: true, backups };\n}\n\nexport async function uninstallFlowSkills(\n\thome = homeDir(),\n\toptions: { dryRun?: boolean } = {},\n) {\n\tconst root = resolveFlowSkillsRoot(home);\n\tconst removed: string[] = [];\n\tconst kept: string[] = [];\n\tconst removedBackups: string[] = [];\n\tlet entries: string[];\n\ttry {\n\t\tentries = await readdir(root);\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n\t\t\treturn { removed, kept, removedBackups };\n\t\t}\n\t\tthrow error;\n\t}\n\tfor (const name of entries) {\n\t\tif (name !== \"flow\" && !name.startsWith(\"flow-\")) continue;\n\t\tconst folder = join(root, name);\n\t\tconst markerContent = await optionalRead(join(folder, MARKER_FILENAME));\n\t\tif (markerContent === null) {\n\t\t\tkept.push(folder);\n\t\t\tcontinue;\n\t\t}\n\t\tconst { pristine, backups } = await inspectManagedFolderForUninstall(\n\t\t\tfolder,\n\t\t\tmarkerContent,\n\t\t);\n\t\tif (!pristine) {\n\t\t\tkept.push(folder);\n\t\t\tcontinue;\n\t\t}\n\t\tfor (const backup of backups) {\n\t\t\tremovedBackups.push(resolveSkillFile(folder, backup));\n\t\t}\n\t\tif (!options.dryRun) {\n\t\t\tawait rm(folder, { recursive: true, force: true });\n\t\t}\n\t\tremoved.push(folder);\n\t}\n\treturn { removed, kept, removedBackups };\n}\n",
5
+ "import { createHash } from \"node:crypto\";\nimport { mkdir, readdir, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { homedir } from \"node:os\";\nimport { dirname, join, normalize, sep } from \"node:path\";\nimport {\n\tFLOW_SKILL_DEFINITIONS,\n\ttype FlowSkillDefinition,\n} from \"./flow-skill-definitions\";\n\nconst MARKER_FILENAME = \".flow-skill-version\";\n\n// Matches the `<file>.backup.<12 hex>` names writeBackup creates, plus its\n// `.N` collision suffix, and captures the embedded content hash. writeBackup\n// names a backup after sha256(content).slice(0, 12), so the hash is a\n// self-describing checksum we can verify against the file's actual content.\nconst BACKUP_FILE_PATTERN = /\\.backup\\.([0-9a-f]{12})(?:\\.\\d+)?$/;\n\nfunction backupHashFromName(relativePath: string): string | null {\n\treturn BACKUP_FILE_PATTERN.exec(relativePath)?.[1] ?? null;\n}\n\n// A file is Flow-created backup residue only when its name matches the pattern\n// AND its content hashes to the embedded checksum. This distinguishes Flow's\n// own backups from an unrelated user file that merely happens to be named like\n// one (e.g. `db.backup.20240115abcd`), which must never be treated as\n// removable residue.\nasync function isFlowCreatedBackup(\n\tfolder: string,\n\trelativePath: string,\n): Promise<boolean> {\n\tconst namedHash = backupHashFromName(relativePath);\n\tif (!namedHash) return false;\n\tconst content = await optionalRead(resolveSkillFile(folder, relativePath));\n\tif (content === null) return false;\n\treturn sha256(content).slice(0, 12) === namedHash;\n}\n\nfunction normalizeNewlines(value: string): string {\n\treturn value.replace(/\\r\\n/g, \"\\n\");\n}\n\ntype FlowLog = (level: \"info\" | \"warn\" | \"error\", message: string) => void;\n\nexport type FlowSkillSyncAction =\n\t| \"installed\"\n\t| \"updated\"\n\t| \"updated_with_backup\"\n\t| \"marker_updated\"\n\t| \"unchanged\"\n\t| \"skipped_foreign\";\n\nexport type FlowSkillSyncResult = {\n\tname: string;\n\taction: FlowSkillSyncAction;\n\tbackupPaths?: string[];\n};\n\n// The sync actions that install or change on-disk skill content and therefore\n// require an OpenCode restart before the refreshed skills load.\nexport const CHANGED_SYNC_ACTIONS: readonly FlowSkillSyncAction[] = [\n\t\"installed\",\n\t\"updated\",\n\t\"updated_with_backup\",\n];\n\nexport function isChangedSyncAction(action: FlowSkillSyncAction): boolean {\n\treturn CHANGED_SYNC_ACTIONS.includes(action);\n}\n\nexport type FlowSkillSyncHealth = {\n\tstatus: \"ok\" | \"restart_required\" | \"action_required\" | \"error\";\n\tversion: string;\n\troot: string;\n\tcheckedAt: string;\n\texpectedSkills: string[];\n\tresults: FlowSkillSyncResult[];\n\tchangedSkills: string[];\n\tactionRequiredSkills: string[];\n\trestartRequired: boolean;\n\tsummary: string;\n\terror?: string;\n};\n\nexport type FlowSkillSetupStatus = {\n\tstatus: \"restart_required\" | \"action_required\" | \"sync_failed\";\n\tsummary: string;\n\tversion: string;\n\troot: string;\n\tchanged?: string[];\n\tactionRequired?: string[];\n\terror?: string;\n};\n\nexport type FlowSkillDoctorSkill = {\n\tname: string;\n\tpath: string;\n\tstatus: \"ok\" | \"missing\" | \"foreign\" | \"incomplete\" | \"edited\" | \"outdated\";\n\tmarkerVersion: string | null;\n\tmissingFiles: string[];\n\teditedFiles: string[];\n\toutdatedFiles: string[];\n\tbackupFiles: string[];\n};\n\nexport type FlowSkillDoctorReport = {\n\tstatus: \"ok\" | \"sync_required\" | \"action_required\";\n\tversion: string;\n\troot: string;\n\texpectedSkills: string[];\n\tskills: FlowSkillDoctorSkill[];\n\tsyncRequiredSkills: string[];\n\tactionRequiredSkills: string[];\n\tunmanagedFlowSkills: string[];\n};\n\nlet latestFlowSkillSyncHealth: FlowSkillSyncHealth | null = null;\n\nfunction homeDir(): string {\n\t// An empty or whitespace-only HOME/USERPROFILE must fall through to the OS\n\t// home dir; otherwise the skills root becomes a cwd-relative path and sync\n\t// writes into (and uninstall rm -rf's) the current directory.\n\tconst configured =\n\t\tprocess.env.HOME?.trim() || process.env.USERPROFILE?.trim();\n\treturn configured || homedir();\n}\n\nexport function resolveFlowSkillsRoot(home = homeDir()): string {\n\treturn join(home, \".config\", \"opencode\", \"skills\");\n}\n\nfunction sha256(value: string): string {\n\treturn createHash(\"sha256\").update(value).digest(\"hex\");\n}\n\nfunction markerFor(definition: FlowSkillDefinition, version: string): string {\n\treturn [\n\t\t`version=${version}`,\n\t\t...definition.files.map(\n\t\t\t(file) => `file=${file.relativePath} sha256=${sha256(file.content)}`,\n\t\t),\n\t\t\"\",\n\t].join(\"\\n\");\n}\n\nasync function optionalRead(path: string): Promise<string | null> {\n\ttry {\n\t\treturn await readFile(path, \"utf8\");\n\t} catch (error) {\n\t\tconst code = (error as NodeJS.ErrnoException).code;\n\t\t// ENOENT: nothing there. ENOTDIR: a path component is a regular file\n\t\t// (e.g. a plain `flow-notes.md` sitting in the skills root), so the\n\t\t// managed file cannot exist — both mean \"absent\", not a hard failure.\n\t\tif (code === \"ENOENT\" || code === \"ENOTDIR\") return null;\n\t\tthrow error;\n\t}\n}\n\nfunction parseMarkerFiles(content: string | null): Map<string, string> {\n\tconst files = new Map<string, string>();\n\tif (!content) return files;\n\tfor (const line of content.split(/\\r?\\n/)) {\n\t\tconst match =\n\t\t\t/^file=(.+) sha256=([a-f0-9]{64})$/.exec(line) ??\n\t\t\t/^file=(.+)=sha256:([a-f0-9]{64})$/.exec(line);\n\t\tif (match?.[1] && match[2]) files.set(match[1], match[2]);\n\t\tconst topLevelHash = /^hash=sha256:([a-f0-9]{64})$/.exec(line);\n\t\tif (topLevelHash?.[1] && !files.has(\"SKILL.md\")) {\n\t\t\tfiles.set(\"SKILL.md\", topLevelHash[1]);\n\t\t}\n\t}\n\treturn files;\n}\n\nfunction parseMarkerVersion(content: string | null): string | null {\n\tif (!content) return null;\n\tfor (const line of content.split(/\\r?\\n/)) {\n\t\tconst match = /^version=(.+)$/.exec(line);\n\t\tif (match?.[1]) return match[1];\n\t}\n\treturn null;\n}\n\nfunction resolveSkillFile(folder: string, relativePath: string): string {\n\tconst resolved = normalize(join(folder, ...relativePath.split(\"/\")));\n\tif (resolved !== folder && resolved.startsWith(`${folder}${sep}`)) {\n\t\treturn resolved;\n\t}\n\tthrow new Error(`Unsafe skill file path '${relativePath}'.`);\n}\n\nasync function writeBackup(path: string, content: string): Promise<string> {\n\tconst basePath = `${path}.backup.${sha256(content).slice(0, 12)}`;\n\tfor (let index = 0; ; index += 1) {\n\t\tconst backupPath = index === 0 ? basePath : `${basePath}.${index}`;\n\t\ttry {\n\t\t\tawait writeFile(backupPath, content, { encoding: \"utf8\", flag: \"wx\" });\n\t\t\treturn backupPath;\n\t\t} catch (error) {\n\t\t\tif ((error as NodeJS.ErrnoException).code === \"EEXIST\") continue;\n\t\t\tthrow error;\n\t\t}\n\t}\n}\n\nasync function syncSkill(\n\tdefinition: FlowSkillDefinition,\n\tversion: string,\n\troot: string,\n): Promise<FlowSkillSyncResult> {\n\tconst folder = join(root, definition.name);\n\tconst markerPath = join(folder, MARKER_FILENAME);\n\tconst markerContent = await optionalRead(markerPath);\n\tconst existingMarkerHashes = parseMarkerFiles(markerContent);\n\tif (markerContent === null) {\n\t\t// No Flow marker proving Flow created this folder: if any managed path\n\t\t// already holds user content, treat the whole folder as user-owned and\n\t\t// never overwrite it. Checking only SKILL.md would silently clobber a\n\t\t// user file at a nested managed path (e.g. references/handoff-format.md)\n\t\t// with no backup.\n\t\tfor (const file of definition.files) {\n\t\t\tconst existing = await optionalRead(\n\t\t\t\tresolveSkillFile(folder, file.relativePath),\n\t\t\t);\n\t\t\tif (existing !== null) {\n\t\t\t\treturn { name: definition.name, action: \"skipped_foreign\" as const };\n\t\t\t}\n\t\t}\n\t}\n\n\tlet changed = false;\n\tconst backupPaths: string[] = [];\n\tconst currentRelativePaths = new Set(\n\t\tdefinition.files.map((file) => file.relativePath),\n\t);\n\tfor (const file of definition.files) {\n\t\tconst path = resolveSkillFile(folder, file.relativePath);\n\t\tconst existing = await optionalRead(path);\n\t\tif (existing === file.content) continue;\n\t\tchanged = true;\n\t\tconst recordedHash = existingMarkerHashes.get(file.relativePath);\n\t\tconst userEdited =\n\t\t\texisting !== null &&\n\t\t\t(recordedHash\n\t\t\t\t? sha256(existing) !== recordedHash\n\t\t\t\t: markerContent !== null);\n\t\tif (userEdited) {\n\t\t\tbackupPaths.push(await writeBackup(path, existing));\n\t\t}\n\t}\n\tfor (const [relativePath, recordedHash] of existingMarkerHashes) {\n\t\tif (currentRelativePaths.has(relativePath)) continue;\n\t\tconst path = resolveSkillFile(folder, relativePath);\n\t\tconst existing = await optionalRead(path);\n\t\tif (existing === null) continue;\n\t\tchanged = true;\n\t\tif (sha256(existing) !== recordedHash) {\n\t\t\tbackupPaths.push(await writeBackup(path, existing));\n\t\t}\n\t\tawait rm(path, { force: true });\n\t}\n\n\tif (\n\t\t!changed &&\n\t\tmarkerContent !== null &&\n\t\tnormalizeNewlines(markerContent) === markerFor(definition, version)\n\t) {\n\t\treturn { name: definition.name, action: \"unchanged\" };\n\t}\n\n\tif (!changed) {\n\t\tawait writeFile(markerPath, markerFor(definition, version), \"utf8\");\n\t\treturn { name: definition.name, action: \"marker_updated\" };\n\t}\n\n\tconst managedSkillExists = markerContent !== null;\n\tfor (const file of definition.files) {\n\t\tconst path = resolveSkillFile(folder, file.relativePath);\n\t\tawait mkdir(dirname(path), { recursive: true });\n\t\tawait writeFile(path, file.content, \"utf8\");\n\t}\n\tawait writeFile(markerPath, markerFor(definition, version), \"utf8\");\n\treturn {\n\t\tname: definition.name,\n\t\taction:\n\t\t\tbackupPaths.length > 0\n\t\t\t\t? \"updated_with_backup\"\n\t\t\t\t: managedSkillExists\n\t\t\t\t\t? \"updated\"\n\t\t\t\t\t: \"installed\",\n\t\t...(backupPaths.length > 0 ? { backupPaths } : {}),\n\t};\n}\n\nfunction expectedSkillNames(): string[] {\n\treturn FLOW_SKILL_DEFINITIONS.map((definition) => definition.name);\n}\n\nfunction createHealth(\n\tversion: string,\n\troot: string,\n\tresults: FlowSkillSyncResult[],\n): FlowSkillSyncHealth {\n\tconst changedSkills = results\n\t\t.filter((result) => isChangedSyncAction(result.action))\n\t\t.map((result) => result.name);\n\tconst actionRequiredSkills = results\n\t\t.filter((result) => result.action === \"skipped_foreign\")\n\t\t.map((result) => result.name);\n\tconst status =\n\t\tactionRequiredSkills.length > 0\n\t\t\t? \"action_required\"\n\t\t\t: changedSkills.length > 0\n\t\t\t\t? \"restart_required\"\n\t\t\t\t: \"ok\";\n\tconst summaryParts: string[] = [];\n\tif (changedSkills.length > 0) {\n\t\tsummaryParts.push(\n\t\t\t`Flow installed or updated skills during this startup (${changedSkills.join(\", \")}). Restart OpenCode before loading Flow skills.`,\n\t\t);\n\t}\n\tif (actionRequiredSkills.length > 0) {\n\t\tsummaryParts.push(\n\t\t\t`Flow found user-owned skill folders for managed skills (${actionRequiredSkills.join(\", \")}). Run ${formatFlowDoctorCommand(version)} for repair guidance.`,\n\t\t);\n\t}\n\tconst summary =\n\t\tsummaryParts.length > 0\n\t\t\t? summaryParts.join(\" \")\n\t\t\t: \"Flow skills are synced.\";\n\treturn {\n\t\tstatus,\n\t\tversion,\n\t\troot,\n\t\tcheckedAt: new Date().toISOString(),\n\t\texpectedSkills: expectedSkillNames(),\n\t\tresults,\n\t\tchangedSkills,\n\t\tactionRequiredSkills,\n\t\trestartRequired: changedSkills.length > 0,\n\t\tsummary,\n\t};\n}\n\nfunction createErrorHealth(\n\tversion: string,\n\troot: string,\n\terror: unknown,\n): FlowSkillSyncHealth {\n\tconst message = error instanceof Error ? error.message : String(error);\n\treturn {\n\t\tstatus: \"error\",\n\t\tversion,\n\t\troot,\n\t\tcheckedAt: new Date().toISOString(),\n\t\texpectedSkills: expectedSkillNames(),\n\t\tresults: [],\n\t\tchangedSkills: [],\n\t\tactionRequiredSkills: [],\n\t\trestartRequired: false,\n\t\tsummary: `Flow skill sync failed: ${message}`,\n\t\terror: message,\n\t};\n}\n\nexport function getLatestFlowSkillSyncHealth(): FlowSkillSyncHealth | null {\n\treturn latestFlowSkillSyncHealth;\n}\n\nexport function formatFlowDoctorCommand(version: string): string {\n\tconst pin = version === \"0.0.0\" ? \"latest\" : version;\n\treturn `npx -y opencode-plugin-flow@${pin} doctor`;\n}\n\nexport function getFlowSkillSetupStatus(\n\thealth = latestFlowSkillSyncHealth,\n): FlowSkillSetupStatus | null {\n\tif (!health || health.status === \"ok\") return null;\n\tconst status = health.status === \"error\" ? \"sync_failed\" : health.status;\n\treturn {\n\t\tstatus,\n\t\tsummary: health.summary,\n\t\tversion: health.version,\n\t\troot: health.root,\n\t\t...(health.changedSkills.length > 0\n\t\t\t? { changed: health.changedSkills }\n\t\t\t: {}),\n\t\t...(health.actionRequiredSkills.length > 0\n\t\t\t? { actionRequired: health.actionRequiredSkills }\n\t\t\t: {}),\n\t\t...(health.error ? { error: health.error } : {}),\n\t};\n}\n\nexport function formatFlowSkillSetupWarning(\n\thealth = latestFlowSkillSyncHealth,\n): string | null {\n\tconst setup = getFlowSkillSetupStatus(health);\n\tif (!setup) return null;\n\treturn [\n\t\t\"Flow setup warning:\",\n\t\tsetup.summary,\n\t\t`Skills root: ${setup.root}`,\n\t\t`Use \\`${formatFlowDoctorCommand(setup.version)}\\` for details.`,\n\t].join(\"\\n\");\n}\n\nexport function resolveFlowPluginVersion(): string {\n\tif (process.env.npm_package_version) return process.env.npm_package_version;\n\ttry {\n\t\tconst require = createRequire(import.meta.url);\n\t\tfor (const path of [\"../package.json\", \"../../package.json\"]) {\n\t\t\ttry {\n\t\t\t\tconst manifest = require(path) as { version?: string };\n\t\t\t\tif (manifest.version) return manifest.version;\n\t\t\t} catch {\n\t\t\t\t// Try the next layout: source tree and bundled dist differ.\n\t\t\t}\n\t\t}\n\t} catch {\n\t\t// Fall through to sentinel.\n\t}\n\treturn \"0.0.0\";\n}\n\nexport async function syncFlowSkills(version: string, home = homeDir()) {\n\tconst root = resolveFlowSkillsRoot(home);\n\treturn Promise.all(\n\t\tFLOW_SKILL_DEFINITIONS.map((definition) =>\n\t\t\tsyncSkill(definition, version, root),\n\t\t),\n\t);\n}\n\nexport async function runFlowSkillSync(\n\tversion: string,\n\tlog: FlowLog,\n\thome = homeDir(),\n): Promise<void> {\n\tconst root = resolveFlowSkillsRoot(home);\n\ttry {\n\t\tconst results = await syncFlowSkills(version, home);\n\t\tlatestFlowSkillSyncHealth = createHealth(version, root, results);\n\t\tconst changed = results.filter((result) =>\n\t\t\tisChangedSyncAction(result.action),\n\t\t);\n\t\tif (changed.length > 0) {\n\t\t\tlog(\n\t\t\t\t\"info\",\n\t\t\t\t`Flow synced skills (${changed.map((item) => `${item.name}:${item.action}`).join(\", \")}). Restart OpenCode if skills were just installed.`,\n\t\t\t);\n\t\t}\n\t\tif (latestFlowSkillSyncHealth.status === \"action_required\") {\n\t\t\tlog(\"warn\", latestFlowSkillSyncHealth.summary);\n\t\t}\n\t} catch (error) {\n\t\tlatestFlowSkillSyncHealth = createErrorHealth(version, root, error);\n\t\tlog(\"warn\", latestFlowSkillSyncHealth.summary);\n\t}\n}\n\nexport async function inspectFlowSkillInstall(\n\tversion = resolveFlowPluginVersion(),\n\thome = homeDir(),\n): Promise<FlowSkillDoctorReport> {\n\tconst root = resolveFlowSkillsRoot(home);\n\tconst expected = new Set(expectedSkillNames());\n\tconst skills = await Promise.all(\n\t\tFLOW_SKILL_DEFINITIONS.map(async (definition) => {\n\t\t\tconst folder = join(root, definition.name);\n\t\t\tconst markerContent = await optionalRead(join(folder, MARKER_FILENAME));\n\t\t\tconst markerVersion = parseMarkerVersion(markerContent);\n\t\t\tconst markerHashes = parseMarkerFiles(markerContent);\n\t\t\tconst existingSkill = await optionalRead(join(folder, \"SKILL.md\"));\n\t\t\tconst backupFiles =\n\t\t\t\tmarkerContent === null ? [] : await listFlowBackupFiles(folder);\n\t\t\tif (existingSkill === null) {\n\t\t\t\treturn {\n\t\t\t\t\tname: definition.name,\n\t\t\t\t\tpath: folder,\n\t\t\t\t\tstatus: \"missing\" as const,\n\t\t\t\t\tmarkerVersion,\n\t\t\t\t\tmissingFiles: definition.files.map((file) => file.relativePath),\n\t\t\t\t\teditedFiles: [],\n\t\t\t\t\toutdatedFiles: [],\n\t\t\t\t\tbackupFiles,\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (markerContent === null) {\n\t\t\t\treturn {\n\t\t\t\t\tname: definition.name,\n\t\t\t\t\tpath: folder,\n\t\t\t\t\tstatus: \"foreign\" as const,\n\t\t\t\t\tmarkerVersion,\n\t\t\t\t\tmissingFiles: [],\n\t\t\t\t\teditedFiles: [],\n\t\t\t\t\toutdatedFiles: [],\n\t\t\t\t\tbackupFiles,\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst missingFiles: string[] = [];\n\t\t\tconst editedFiles: string[] = [];\n\t\t\tconst outdatedFiles: string[] = [];\n\t\t\tfor (const file of definition.files) {\n\t\t\t\tconst existing = await optionalRead(\n\t\t\t\t\tresolveSkillFile(folder, file.relativePath),\n\t\t\t\t);\n\t\t\t\tif (existing === null) {\n\t\t\t\t\tmissingFiles.push(file.relativePath);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (existing === file.content) continue;\n\t\t\t\tconst recordedHash = markerHashes.get(file.relativePath);\n\t\t\t\tif (recordedHash && sha256(existing) !== recordedHash) {\n\t\t\t\t\teditedFiles.push(file.relativePath);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\toutdatedFiles.push(file.relativePath);\n\t\t\t}\n\t\t\t// Compare newline-normalized: a CRLF-converted marker (Windows editor,\n\t\t\t// autocrlf) still hashes every file correctly, so it must not be\n\t\t\t// reported as drifted/outdated purely on line endings.\n\t\t\tconst markerDrift =\n\t\t\t\tnormalizeNewlines(markerContent) !== markerFor(definition, version);\n\t\t\tconst status: FlowSkillDoctorSkill[\"status\"] =\n\t\t\t\tmissingFiles.length > 0\n\t\t\t\t\t? \"incomplete\"\n\t\t\t\t\t: editedFiles.length > 0\n\t\t\t\t\t\t? \"edited\"\n\t\t\t\t\t\t: markerDrift || outdatedFiles.length > 0\n\t\t\t\t\t\t\t? \"outdated\"\n\t\t\t\t\t\t\t: \"ok\";\n\t\t\treturn {\n\t\t\t\tname: definition.name,\n\t\t\t\tpath: folder,\n\t\t\t\tstatus,\n\t\t\t\tmarkerVersion,\n\t\t\t\tmissingFiles,\n\t\t\t\teditedFiles,\n\t\t\t\toutdatedFiles,\n\t\t\t\tbackupFiles,\n\t\t\t};\n\t\t}),\n\t);\n\n\tlet entries: string[] = [];\n\ttry {\n\t\tentries = await readdir(root);\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n\t}\n\tconst unmanagedFlowSkills = entries\n\t\t.filter(\n\t\t\t(name) =>\n\t\t\t\t(name === \"flow\" || name.startsWith(\"flow-\")) && !expected.has(name),\n\t\t)\n\t\t.map((name) => join(root, name));\n\n\tconst syncRequiredSkills = skills\n\t\t.filter((skill) =>\n\t\t\t[\"missing\", \"incomplete\", \"outdated\"].includes(skill.status),\n\t\t)\n\t\t.map((skill) => skill.name);\n\tconst actionRequiredSkills = skills\n\t\t.filter(\n\t\t\t(skill) =>\n\t\t\t\t[\"foreign\", \"edited\"].includes(skill.status) ||\n\t\t\t\tskill.backupFiles.length > 0,\n\t\t)\n\t\t.map((skill) => skill.name);\n\tconst actionRequired = actionRequiredSkills.length > 0;\n\tconst syncRequired = syncRequiredSkills.length > 0;\n\treturn {\n\t\tstatus: actionRequired\n\t\t\t? \"action_required\"\n\t\t\t: syncRequired\n\t\t\t\t? \"sync_required\"\n\t\t\t\t: \"ok\",\n\t\tversion,\n\t\troot,\n\t\texpectedSkills: [...expected],\n\t\tskills,\n\t\tsyncRequiredSkills,\n\t\tactionRequiredSkills,\n\t\tunmanagedFlowSkills,\n\t};\n}\n\nfunction appendSkillList(\n\tlines: string[],\n\tlabel: string,\n\tskills: string[],\n): void {\n\tif (skills.length === 0) return;\n\tlines.push(`- ${label}: ${skills.join(\", \")}`);\n}\n\nexport function formatFlowSkillDoctor(report: FlowSkillDoctorReport): string {\n\tconst lines = [\n\t\t\"Flow doctor\",\n\t\t`- status: ${report.status}`,\n\t\t`- plugin version: ${report.version}`,\n\t\t`- skills root: ${report.root}`,\n\t\t`- expected skills: ${report.expectedSkills.join(\", \")}`,\n\t];\n\tappendSkillList(\n\t\tlines,\n\t\t\"startup sync can install/update\",\n\t\treport.syncRequiredSkills,\n\t);\n\tappendSkillList(lines, \"needs user decision\", report.actionRequiredSkills);\n\tlines.push(\"\", \"Skills:\");\n\tfor (const skill of report.skills) {\n\t\tlines.push(\n\t\t\t`- ${skill.name}: ${skill.status} (${skill.path})${\n\t\t\t\tskill.markerVersion ? ` marker=${skill.markerVersion}` : \"\"\n\t\t\t}`,\n\t\t);\n\t\tif (skill.missingFiles.length > 0) {\n\t\t\tlines.push(` missing: ${skill.missingFiles.join(\", \")}`);\n\t\t}\n\t\tif (skill.editedFiles.length > 0) {\n\t\t\tlines.push(` edited: ${skill.editedFiles.join(\", \")}`);\n\t\t}\n\t\tif (skill.outdatedFiles.length > 0) {\n\t\t\tlines.push(` outdated: ${skill.outdatedFiles.join(\", \")}`);\n\t\t}\n\t\tif (skill.backupFiles.length > 0) {\n\t\t\tlines.push(` backups: ${skill.backupFiles.join(\", \")}`);\n\t\t}\n\t}\n\tif (report.unmanagedFlowSkills.length > 0) {\n\t\tlines.push(\"\", \"Unmanaged Flow-like skill folders:\");\n\t\tfor (const path of report.unmanagedFlowSkills) lines.push(`- ${path}`);\n\t}\n\tlines.push(\"\", \"Recommendation:\");\n\tif (report.status === \"ok\") {\n\t\tlines.push(\"- Flow skills are present and current.\");\n\t} else if (report.status === \"sync_required\") {\n\t\tlines.push(\n\t\t\t\"- Start or restart OpenCode with opencode-plugin-flow enabled so startup sync can install or update the listed skills. If Flow then reports restart_required, restart OpenCode once more so the refreshed skill registry is used.\",\n\t\t);\n\t} else {\n\t\tlines.push(\n\t\t\t\"- Resolve user-owned or edited managed skill folders, then restart OpenCode. Move a folder aside to let Flow recreate it, or keep it intentionally as a local override.\",\n\t\t);\n\t\tif (report.skills.some((skill) => skill.backupFiles.length > 0)) {\n\t\t\tlines.push(\n\t\t\t\t\"- Flow saved earlier local edits as .backup files; review each one and delete it once the saved copy is no longer needed. Sync ignores them, and uninstall removes them (naming each) along with the folder.\",\n\t\t\t);\n\t\t}\n\t}\n\tlines.push(`- Details command: ${formatFlowDoctorCommand(report.version)}`);\n\treturn `${lines.join(\"\\n\")}\\n`;\n}\n\nasync function listSkillFolderFiles(folder: string): Promise<string[]> {\n\tconst entries = await readdir(folder, {\n\t\trecursive: true,\n\t\twithFileTypes: true,\n\t});\n\treturn entries\n\t\t.filter((entry) => entry.isFile())\n\t\t.map((entry) =>\n\t\t\tjoin(entry.parentPath, entry.name)\n\t\t\t\t.slice(folder.length + 1)\n\t\t\t\t.split(sep)\n\t\t\t\t.join(\"/\"),\n\t\t);\n}\n\nasync function listFlowBackupFiles(folder: string): Promise<string[]> {\n\tlet names: string[];\n\ttry {\n\t\tnames = await listSkillFolderFiles(folder);\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code === \"ENOENT\") return [];\n\t\tthrow error;\n\t}\n\tconst backups: string[] = [];\n\tfor (const name of names) {\n\t\tif (await isFlowCreatedBackup(folder, name)) backups.push(name);\n\t}\n\treturn backups;\n}\n\n// A managed folder is removable when every non-marker file is either a pristine\n// managed file or Flow-created `.backup` residue. Backups hold the user's own\n// earlier edits, so they are returned separately: removable, but reported so the\n// deletion is never silent.\nasync function inspectManagedFolderForUninstall(\n\tfolder: string,\n\tmarkerContent: string,\n): Promise<{ pristine: boolean; backups: string[] }> {\n\tconst hashes = parseMarkerFiles(markerContent);\n\tif (hashes.size === 0) return { pristine: false, backups: [] };\n\tconst backups: string[] = [];\n\tfor (const relativePath of await listSkillFolderFiles(folder)) {\n\t\tif (relativePath === MARKER_FILENAME) continue;\n\t\tconst recordedHash = hashes.get(relativePath);\n\t\tif (recordedHash !== undefined) {\n\t\t\tconst content = await optionalRead(\n\t\t\t\tresolveSkillFile(folder, relativePath),\n\t\t\t);\n\t\t\tif (content === null || sha256(content) !== recordedHash) {\n\t\t\t\treturn { pristine: false, backups };\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\t// Not a managed file: removable only if it is genuinely Flow-created\n\t\t// backup residue (name + content checksum). Any other unknown file is\n\t\t// the user's own and keeps the folder.\n\t\tif (await isFlowCreatedBackup(folder, relativePath)) {\n\t\t\tbackups.push(relativePath);\n\t\t\tcontinue;\n\t\t}\n\t\treturn { pristine: false, backups };\n\t}\n\treturn { pristine: true, backups };\n}\n\nexport async function uninstallFlowSkills(\n\thome = homeDir(),\n\toptions: { dryRun?: boolean } = {},\n) {\n\tconst root = resolveFlowSkillsRoot(home);\n\tconst removed: string[] = [];\n\tconst kept: string[] = [];\n\tconst removedBackups: string[] = [];\n\tlet entries: string[];\n\ttry {\n\t\tentries = await readdir(root);\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n\t\t\treturn { removed, kept, removedBackups };\n\t\t}\n\t\tthrow error;\n\t}\n\tfor (const name of entries) {\n\t\tif (name !== \"flow\" && !name.startsWith(\"flow-\")) continue;\n\t\tconst folder = join(root, name);\n\t\tconst markerContent = await optionalRead(join(folder, MARKER_FILENAME));\n\t\tif (markerContent === null) {\n\t\t\tkept.push(folder);\n\t\t\tcontinue;\n\t\t}\n\t\tconst { pristine, backups } = await inspectManagedFolderForUninstall(\n\t\t\tfolder,\n\t\t\tmarkerContent,\n\t\t);\n\t\tif (!pristine) {\n\t\t\tkept.push(folder);\n\t\t\tcontinue;\n\t\t}\n\t\tfor (const backup of backups) {\n\t\t\tremovedBackups.push(resolveSkillFile(folder, backup));\n\t\t}\n\t\tif (!options.dryRun) {\n\t\t\tawait rm(folder, { recursive: true, force: true });\n\t\t}\n\t\tremoved.push(folder);\n\t}\n\treturn { removed, kept, removedBackups };\n}\n",
6
6
  "import flowHandoffFormatDoc from \"../../skills/flow/references/handoff-format.md\" with {\n\ttype: \"text\",\n};\nimport flowParallelOrchestrationDoc from \"../../skills/flow/references/parallel-orchestration.md\" with {\n\ttype: \"text\",\n};\nimport flowParallelPassExampleDoc from \"../../skills/flow/references/parallel-pass-example.md\" with {\n\ttype: \"text\",\n};\nimport flowRecoveryPlaybookDoc from \"../../skills/flow/references/recovery-playbook.md\" with {\n\ttype: \"text\",\n};\nimport flowSkillDoc from \"../../skills/flow/SKILL.md\" with { type: \"text\" };\nimport flowCommitSkillDoc from \"../../skills/flow-commit/SKILL.md\" with {\n\ttype: \"text\",\n};\nimport flowDeslopRefactorWorkflowDoc from \"../../skills/flow-deslop/references/refactor-workflow.md\" with {\n\ttype: \"text\",\n};\nimport flowDeslopSmellRubricDoc from \"../../skills/flow-deslop/references/smell-rubric.md\" with {\n\ttype: \"text\",\n};\nimport flowDeslopSkillDoc from \"../../skills/flow-deslop/SKILL.md\" with {\n\ttype: \"text\",\n};\nimport flowPlanParallelDiscoveryDoc from \"../../skills/flow-plan/references/parallel-discovery.md\" with {\n\ttype: \"text\",\n};\nimport flowPlanPlanningExamplesDoc from \"../../skills/flow-plan/references/planning-examples.md\" with {\n\ttype: \"text\",\n};\nimport flowPlanSkillDoc from \"../../skills/flow-plan/SKILL.md\" with {\n\ttype: \"text\",\n};\nimport flowReviewReviewRubricDoc from \"../../skills/flow-review/references/review-rubric.md\" with {\n\ttype: \"text\",\n};\nimport flowReviewSkillDoc from \"../../skills/flow-review/SKILL.md\" with {\n\ttype: \"text\",\n};\nimport flowRunAuditRubricDoc from \"../../skills/flow-run/references/audit-rubric.md\" with {\n\ttype: \"text\",\n};\nimport flowRunValidationRubricDoc from \"../../skills/flow-run/references/validation-rubric.md\" with {\n\ttype: \"text\",\n};\nimport flowRunSkillDoc from \"../../skills/flow-run/SKILL.md\" with {\n\ttype: \"text\",\n};\nimport flowTestSkillDoc from \"../../skills/flow-test/SKILL.md\" with {\n\ttype: \"text\",\n};\nimport flowUiQualityUiRubricDoc from \"../../skills/flow-ui-quality/references/ui-rubric.md\" with {\n\ttype: \"text\",\n};\nimport flowUiQualityVisualVerificationDoc from \"../../skills/flow-ui-quality/references/visual-verification.md\" with {\n\ttype: \"text\",\n};\nimport flowUiQualitySkillDoc from \"../../skills/flow-ui-quality/SKILL.md\" with {\n\ttype: \"text\",\n};\n\nexport type FlowSkillFile = {\n\trelativePath: string;\n\tcontent: string;\n};\n\nexport type FlowSkillDefinition = {\n\tname: string;\n\tfiles: FlowSkillFile[];\n};\n\nexport const FLOW_SKILL_DEFINITIONS: readonly FlowSkillDefinition[] = [\n\t{\n\t\tname: \"flow\",\n\t\tfiles: [\n\t\t\t{ relativePath: \"SKILL.md\", content: flowSkillDoc },\n\t\t\t{\n\t\t\t\trelativePath: \"references/recovery-playbook.md\",\n\t\t\t\tcontent: flowRecoveryPlaybookDoc,\n\t\t\t},\n\t\t\t{\n\t\t\t\trelativePath: \"references/parallel-orchestration.md\",\n\t\t\t\tcontent: flowParallelOrchestrationDoc,\n\t\t\t},\n\t\t\t{\n\t\t\t\trelativePath: \"references/parallel-pass-example.md\",\n\t\t\t\tcontent: flowParallelPassExampleDoc,\n\t\t\t},\n\t\t\t{\n\t\t\t\trelativePath: \"references/handoff-format.md\",\n\t\t\t\tcontent: flowHandoffFormatDoc,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"flow-plan\",\n\t\tfiles: [\n\t\t\t{ relativePath: \"SKILL.md\", content: flowPlanSkillDoc },\n\t\t\t{\n\t\t\t\trelativePath: \"references/planning-examples.md\",\n\t\t\t\tcontent: flowPlanPlanningExamplesDoc,\n\t\t\t},\n\t\t\t{\n\t\t\t\trelativePath: \"references/parallel-discovery.md\",\n\t\t\t\tcontent: flowPlanParallelDiscoveryDoc,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"flow-run\",\n\t\tfiles: [\n\t\t\t{ relativePath: \"SKILL.md\", content: flowRunSkillDoc },\n\t\t\t{\n\t\t\t\trelativePath: \"references/validation-rubric.md\",\n\t\t\t\tcontent: flowRunValidationRubricDoc,\n\t\t\t},\n\t\t\t{\n\t\t\t\trelativePath: \"references/audit-rubric.md\",\n\t\t\t\tcontent: flowRunAuditRubricDoc,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"flow-test\",\n\t\tfiles: [{ relativePath: \"SKILL.md\", content: flowTestSkillDoc }],\n\t},\n\t{\n\t\tname: \"flow-review\",\n\t\tfiles: [\n\t\t\t{ relativePath: \"SKILL.md\", content: flowReviewSkillDoc },\n\t\t\t{\n\t\t\t\trelativePath: \"references/review-rubric.md\",\n\t\t\t\tcontent: flowReviewReviewRubricDoc,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"flow-deslop\",\n\t\tfiles: [\n\t\t\t{ relativePath: \"SKILL.md\", content: flowDeslopSkillDoc },\n\t\t\t{\n\t\t\t\trelativePath: \"references/smell-rubric.md\",\n\t\t\t\tcontent: flowDeslopSmellRubricDoc,\n\t\t\t},\n\t\t\t{\n\t\t\t\trelativePath: \"references/refactor-workflow.md\",\n\t\t\t\tcontent: flowDeslopRefactorWorkflowDoc,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"flow-ui-quality\",\n\t\tfiles: [\n\t\t\t{ relativePath: \"SKILL.md\", content: flowUiQualitySkillDoc },\n\t\t\t{\n\t\t\t\trelativePath: \"references/ui-rubric.md\",\n\t\t\t\tcontent: flowUiQualityUiRubricDoc,\n\t\t\t},\n\t\t\t{\n\t\t\t\trelativePath: \"references/visual-verification.md\",\n\t\t\t\tcontent: flowUiQualityVisualVerificationDoc,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"flow-commit\",\n\t\tfiles: [{ relativePath: \"SKILL.md\", content: flowCommitSkillDoc }],\n\t},\n];\n",
7
- "import {\n\ttype FlowSkillDoctorReport,\n\tformatFlowSkillDoctor,\n\tinspectFlowSkillInstall,\n\tresolveFlowPluginVersion,\n\tsyncFlowSkills,\n\tuninstallFlowSkills,\n} from \"./distribution/sync\";\n\nfunction usage(): string {\n\treturn [\n\t\t\"usage: opencode-plugin-flow <doctor|sync|uninstall> [options]\",\n\t\t\"\",\n\t\t\"commands:\",\n\t\t\" doctor Inspect managed Flow skills\",\n\t\t\" sync Install or refresh managed Flow skills\",\n\t\t\" uninstall Remove pristine Flow-owned managed skills\",\n\t\t\"\",\n\t\t\"doctor options:\",\n\t\t\" --json Write the doctor report as JSON\",\n\t\t\" --check, --strict Exit nonzero when doctor status is not ok\",\n\t\t\"\",\n\t\t\"uninstall options:\",\n\t\t\" --dry-run Preview removals without deleting anything\",\n\t\t\"\",\n\t\t\"global options:\",\n\t\t\" --help Show this help\",\n\t\t\" --version Print the plugin version\",\n\t].join(\"\\n\");\n}\n\nfunction hasOnlyKnownFlags(flags: string[], known: Set<string>): boolean {\n\treturn flags.every((flag) => known.has(flag));\n}\n\nfunction writeDoctorReport(\n\treport: FlowSkillDoctorReport,\n\toptions: { json: boolean },\n): void {\n\tif (options.json) {\n\t\tprocess.stdout.write(`${JSON.stringify(report, null, 2)}\\n`);\n\t\treturn;\n\t}\n\tprocess.stdout.write(formatFlowSkillDoctor(report));\n}\n\nasync function main(argv: string[]): Promise<void> {\n\tconst command = argv[2];\n\tconst flags = argv.slice(3);\n\tif (command === \"--help\" || command === \"-h\") {\n\t\tprocess.stdout.write(`${usage()}\\n`);\n\t\treturn;\n\t}\n\tif (command === \"--version\" || command === \"-v\") {\n\t\tprocess.stdout.write(`${resolveFlowPluginVersion()}\\n`);\n\t\treturn;\n\t}\n\tif (command !== \"uninstall\" && command !== \"doctor\" && command !== \"sync\") {\n\t\tprocess.stderr.write(`${usage()}\\n`);\n\t\tprocess.exitCode = 2;\n\t\treturn;\n\t}\n\tif (command === \"doctor\") {\n\t\tconst knownDoctorFlags = new Set([\"--json\", \"--check\", \"--strict\"]);\n\t\tif (!hasOnlyKnownFlags(flags, knownDoctorFlags)) {\n\t\t\tprocess.stderr.write(`${usage()}\\n`);\n\t\t\tprocess.exitCode = 2;\n\t\t\treturn;\n\t\t}\n\t\tconst report = await inspectFlowSkillInstall();\n\t\twriteDoctorReport(report, { json: flags.includes(\"--json\") });\n\t\tif (\n\t\t\t(report.status === \"sync_required\" ||\n\t\t\t\treport.status === \"action_required\") &&\n\t\t\t(flags.includes(\"--check\") || flags.includes(\"--strict\"))\n\t\t) {\n\t\t\tprocess.exitCode = 1;\n\t\t}\n\t\treturn;\n\t}\n\tconst knownUninstallFlags = new Set([\"--dry-run\"]);\n\tif (\n\t\tcommand === \"uninstall\" &&\n\t\t!hasOnlyKnownFlags(flags, knownUninstallFlags)\n\t) {\n\t\tprocess.stderr.write(`${usage()}\\n`);\n\t\tprocess.exitCode = 2;\n\t\treturn;\n\t}\n\tif (command === \"sync\" && flags.length > 0) {\n\t\tprocess.stderr.write(`${usage()}\\n`);\n\t\tprocess.exitCode = 2;\n\t\treturn;\n\t}\n\tif (command === \"sync\") {\n\t\tconst version = resolveFlowPluginVersion();\n\t\tconst results = await syncFlowSkills(version);\n\t\tconst changed = results.filter((result) =>\n\t\t\t[\"installed\", \"updated\", \"updated_with_backup\"].includes(result.action),\n\t\t);\n\t\tconst actionRequired = results.filter(\n\t\t\t(result) => result.action === \"skipped_foreign\",\n\t\t);\n\t\tprocess.stdout.write(`Flow skill sync (${version})\\n`);\n\t\tfor (const result of results) {\n\t\t\tprocess.stdout.write(`- ${result.name}: ${result.action}\\n`);\n\t\t\tfor (const backupPath of result.backupPaths ?? []) {\n\t\t\t\tprocess.stdout.write(` backup: ${backupPath}\\n`);\n\t\t\t}\n\t\t}\n\t\tif (changed.length > 0) {\n\t\t\tprocess.stdout.write(\n\t\t\t\t\"Restart OpenCode so the refreshed skill registry is used.\\n\",\n\t\t\t);\n\t\t}\n\t\tif (actionRequired.length > 0) {\n\t\t\tprocess.stdout.write(\n\t\t\t\t\"Some managed skill folders are user-owned or edited; run doctor for repair guidance.\\n\",\n\t\t\t);\n\t\t}\n\t\treturn;\n\t}\n\tconst dryRun = flags.includes(\"--dry-run\");\n\tconst result = await uninstallFlowSkills(undefined, { dryRun });\n\tfor (const path of result.removed) {\n\t\tprocess.stdout.write(\n\t\t\t`${dryRun ? \"Would remove\" : \"Removed\"} Flow skill: ${path}\\n`,\n\t\t);\n\t}\n\tfor (const path of result.kept) {\n\t\tprocess.stdout.write(`Kept non-Flow or user-edited skill: ${path}\\n`);\n\t}\n\tif (result.removedBackups.length > 0) {\n\t\tprocess.stdout.write(\n\t\t\t`${dryRun ? \"Would remove\" : \"Removed\"} Flow-created backup files holding your earlier edits:\\n`,\n\t\t);\n\t\tfor (const path of result.removedBackups) {\n\t\t\tprocess.stdout.write(` ${path}\\n`);\n\t\t}\n\t}\n\tprocess.stdout.write(\n\t\tdryRun\n\t\t\t? \"Dry run: no files were removed.\\n\"\n\t\t\t: \"Remove opencode-plugin-flow from your OpenCode plugin config and restart OpenCode.\\n\",\n\t);\n}\n\nmain(process.argv).catch((error) => {\n\tprocess.stderr.write(\n\t\t`${error instanceof Error ? error.message : String(error)}\\n`,\n\t);\n\tprocess.exitCode = 1;\n});\n"
7
+ "import {\n\ttype FlowSkillDoctorReport,\n\tformatFlowSkillDoctor,\n\tinspectFlowSkillInstall,\n\tisChangedSyncAction,\n\tresolveFlowPluginVersion,\n\tsyncFlowSkills,\n\tuninstallFlowSkills,\n} from \"./distribution/sync\";\n\nfunction usage(): string {\n\treturn [\n\t\t\"usage: opencode-plugin-flow <doctor|sync|uninstall> [options]\",\n\t\t\"\",\n\t\t\"commands:\",\n\t\t\" doctor Inspect managed Flow skills\",\n\t\t\" sync Install or refresh managed Flow skills\",\n\t\t\" uninstall Remove pristine Flow-owned managed skills\",\n\t\t\"\",\n\t\t\"doctor options:\",\n\t\t\" --json Write the doctor report as JSON\",\n\t\t\" --check, --strict Exit nonzero when doctor status is not ok\",\n\t\t\"\",\n\t\t\"uninstall options:\",\n\t\t\" --dry-run Preview removals without deleting anything\",\n\t\t\"\",\n\t\t\"global options:\",\n\t\t\" --help Show this help\",\n\t\t\" --version Print the plugin version\",\n\t].join(\"\\n\");\n}\n\nfunction hasOnlyKnownFlags(flags: string[], known: Set<string>): boolean {\n\treturn flags.every((flag) => known.has(flag));\n}\n\nfunction writeDoctorReport(\n\treport: FlowSkillDoctorReport,\n\toptions: { json: boolean },\n): void {\n\tif (options.json) {\n\t\tprocess.stdout.write(`${JSON.stringify(report, null, 2)}\\n`);\n\t\treturn;\n\t}\n\tprocess.stdout.write(formatFlowSkillDoctor(report));\n}\n\nasync function main(argv: string[]): Promise<void> {\n\tconst command = argv[2];\n\tconst flags = argv.slice(3);\n\tif (command === \"--help\" || command === \"-h\") {\n\t\tprocess.stdout.write(`${usage()}\\n`);\n\t\treturn;\n\t}\n\tif (command === \"--version\" || command === \"-v\") {\n\t\tprocess.stdout.write(`${resolveFlowPluginVersion()}\\n`);\n\t\treturn;\n\t}\n\tif (command !== \"uninstall\" && command !== \"doctor\" && command !== \"sync\") {\n\t\tprocess.stderr.write(`${usage()}\\n`);\n\t\tprocess.exitCode = 2;\n\t\treturn;\n\t}\n\tif (command === \"doctor\") {\n\t\tconst knownDoctorFlags = new Set([\"--json\", \"--check\", \"--strict\"]);\n\t\tif (!hasOnlyKnownFlags(flags, knownDoctorFlags)) {\n\t\t\tprocess.stderr.write(`${usage()}\\n`);\n\t\t\tprocess.exitCode = 2;\n\t\t\treturn;\n\t\t}\n\t\tconst report = await inspectFlowSkillInstall();\n\t\twriteDoctorReport(report, { json: flags.includes(\"--json\") });\n\t\tif (\n\t\t\t(report.status === \"sync_required\" ||\n\t\t\t\treport.status === \"action_required\") &&\n\t\t\t(flags.includes(\"--check\") || flags.includes(\"--strict\"))\n\t\t) {\n\t\t\tprocess.exitCode = 1;\n\t\t}\n\t\treturn;\n\t}\n\tconst knownUninstallFlags = new Set([\"--dry-run\"]);\n\tif (\n\t\tcommand === \"uninstall\" &&\n\t\t!hasOnlyKnownFlags(flags, knownUninstallFlags)\n\t) {\n\t\tprocess.stderr.write(`${usage()}\\n`);\n\t\tprocess.exitCode = 2;\n\t\treturn;\n\t}\n\tif (command === \"sync\" && flags.length > 0) {\n\t\tprocess.stderr.write(`${usage()}\\n`);\n\t\tprocess.exitCode = 2;\n\t\treturn;\n\t}\n\tif (command === \"sync\") {\n\t\tconst version = resolveFlowPluginVersion();\n\t\tconst results = await syncFlowSkills(version);\n\t\tconst changed = results.filter((result) =>\n\t\t\tisChangedSyncAction(result.action),\n\t\t);\n\t\tconst actionRequired = results.filter(\n\t\t\t(result) => result.action === \"skipped_foreign\",\n\t\t);\n\t\tprocess.stdout.write(`Flow skill sync (${version})\\n`);\n\t\tfor (const result of results) {\n\t\t\tprocess.stdout.write(`- ${result.name}: ${result.action}\\n`);\n\t\t\tfor (const backupPath of result.backupPaths ?? []) {\n\t\t\t\tprocess.stdout.write(` backup: ${backupPath}\\n`);\n\t\t\t}\n\t\t}\n\t\tif (changed.length > 0) {\n\t\t\tprocess.stdout.write(\n\t\t\t\t\"Restart OpenCode so the refreshed skill registry is used.\\n\",\n\t\t\t);\n\t\t}\n\t\tif (actionRequired.length > 0) {\n\t\t\tprocess.stdout.write(\n\t\t\t\t\"Some managed skill folders are user-owned or edited; run doctor for repair guidance.\\n\",\n\t\t\t);\n\t\t}\n\t\treturn;\n\t}\n\tconst dryRun = flags.includes(\"--dry-run\");\n\tconst result = await uninstallFlowSkills(undefined, { dryRun });\n\tfor (const path of result.removed) {\n\t\tprocess.stdout.write(\n\t\t\t`${dryRun ? \"Would remove\" : \"Removed\"} Flow skill: ${path}\\n`,\n\t\t);\n\t}\n\tfor (const path of result.kept) {\n\t\tprocess.stdout.write(`Kept non-Flow or user-edited skill: ${path}\\n`);\n\t}\n\tif (result.removedBackups.length > 0) {\n\t\tprocess.stdout.write(\n\t\t\t`${dryRun ? \"Would remove\" : \"Removed\"} Flow-created backup files holding your earlier edits:\\n`,\n\t\t);\n\t\tfor (const path of result.removedBackups) {\n\t\t\tprocess.stdout.write(` ${path}\\n`);\n\t\t}\n\t}\n\tprocess.stdout.write(\n\t\tdryRun\n\t\t\t? \"Dry run: no files were removed.\\n\"\n\t\t\t: \"Remove opencode-plugin-flow from your OpenCode plugin config and restart OpenCode.\\n\",\n\t);\n}\n\nmain(process.argv).catch((error) => {\n\tprocess.stderr.write(\n\t\t`${error instanceof Error ? error.message : String(error)}\\n`,\n\t);\n\tprocess.exitCode = 1;\n});\n"
8
8
  ],
9
- "mappings": ";;;AAAA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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",
10
- "debugId": "056C129404DFA30D64756E2164756E21",
9
+ "mappings": ";;;AAAA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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",
10
+ "debugId": "B10F4D7F094C050864756E2164756E21",
11
11
  "names": []
12
12
  }
@@ -5,6 +5,8 @@ export type FlowSkillSyncResult = {
5
5
  action: FlowSkillSyncAction;
6
6
  backupPaths?: string[];
7
7
  };
8
+ export declare const CHANGED_SYNC_ACTIONS: readonly FlowSkillSyncAction[];
9
+ export declare function isChangedSyncAction(action: FlowSkillSyncAction): boolean;
8
10
  export type FlowSkillSyncHealth = {
9
11
  status: "ok" | "restart_required" | "action_required" | "error";
10
12
  version: string;