maskweaver 0.9.4 → 0.9.6

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.
Files changed (229) hide show
  1. package/README.ko.md +638 -592
  2. package/README.md +671 -667
  3. package/dist/cli/doctor.js +5 -21
  4. package/dist/cli/install.d.ts +0 -8
  5. package/dist/cli/install.js +0 -39
  6. package/dist/context/config.d.ts +0 -22
  7. package/dist/context/config.js +0 -28
  8. package/dist/context/feature.d.ts +0 -39
  9. package/dist/context/feature.js +0 -77
  10. package/dist/context/files.d.ts +0 -13
  11. package/dist/context/files.js +1 -24
  12. package/dist/context/index.d.ts +0 -7
  13. package/dist/context/index.js +0 -12
  14. package/dist/context/project.d.ts +0 -21
  15. package/dist/context/project.js +0 -30
  16. package/dist/context/types.d.ts +0 -48
  17. package/dist/context/types.js +0 -12
  18. package/dist/context/utils.d.ts +0 -18
  19. package/dist/context/utils.js +0 -27
  20. package/dist/core/engine/promptBuilder.d.ts +0 -17
  21. package/dist/core/engine/promptBuilder.js +0 -28
  22. package/dist/core/index.d.ts +0 -6
  23. package/dist/core/index.js +0 -9
  24. package/dist/core/loader/MaskLoader.d.ts +0 -23
  25. package/dist/core/loader/MaskLoader.js +0 -29
  26. package/dist/core/schema/types.d.ts +0 -47
  27. package/dist/core/schema/types.js +0 -6
  28. package/dist/core/schema/validator.d.ts +0 -14
  29. package/dist/core/schema/validator.js +0 -18
  30. package/dist/i18n/index.d.ts +0 -18
  31. package/dist/i18n/index.js +4 -23
  32. package/dist/index.d.ts +0 -8
  33. package/dist/index.js +0 -8
  34. package/dist/lib.d.ts +0 -5
  35. package/dist/lib.js +0 -12
  36. package/dist/memory/chunking.d.ts +0 -22
  37. package/dist/memory/chunking.js +2 -37
  38. package/dist/memory/core.d.ts +0 -29
  39. package/dist/memory/core.js +1 -52
  40. package/dist/memory/index.d.ts +0 -5
  41. package/dist/memory/index.js +0 -10
  42. package/dist/memory/indexer.d.ts +0 -21
  43. package/dist/memory/indexer.js +0 -44
  44. package/dist/memory/providers/examples.d.ts +0 -5
  45. package/dist/memory/providers/examples.js +4 -64
  46. package/dist/memory/providers/factory.d.ts +0 -44
  47. package/dist/memory/providers/factory.js +0 -46
  48. package/dist/memory/providers/index.d.ts +0 -26
  49. package/dist/memory/providers/index.js +0 -28
  50. package/dist/memory/providers/ollama.d.ts +0 -6
  51. package/dist/memory/providers/ollama.js +1 -8
  52. package/dist/memory/providers/openai.d.ts +0 -6
  53. package/dist/memory/providers/openai.js +1 -8
  54. package/dist/memory/providers/openrouter.d.ts +0 -6
  55. package/dist/memory/providers/openrouter.js +0 -8
  56. package/dist/memory/providers/text-only.d.ts +0 -13
  57. package/dist/memory/providers/text-only.js +0 -17
  58. package/dist/memory/providers/types.d.ts +0 -39
  59. package/dist/memory/providers/types.js +0 -7
  60. package/dist/memory/providers/voyage.d.ts +0 -22
  61. package/dist/memory/providers/voyage.js +1 -24
  62. package/dist/memory/search/hybrid.d.ts +0 -12
  63. package/dist/memory/search/hybrid.js +1 -22
  64. package/dist/memory/store/sqlite.d.ts +0 -72
  65. package/dist/memory/store/sqlite.js +4 -127
  66. package/dist/plugin/config/index.d.ts +0 -112
  67. package/dist/plugin/config/index.js +0 -115
  68. package/dist/plugin/index.d.ts +0 -13
  69. package/dist/plugin/index.js +1 -123
  70. package/dist/plugin/tools/command-registry.d.ts +0 -6
  71. package/dist/plugin/tools/command-registry.js +0 -14
  72. package/dist/plugin/tools/context.d.ts +0 -12
  73. package/dist/plugin/tools/context.js +0 -58
  74. package/dist/plugin/tools/maskSave.d.ts +0 -3
  75. package/dist/plugin/tools/maskSave.js +0 -3
  76. package/dist/plugin/tools/memoryGet.d.ts +0 -3
  77. package/dist/plugin/tools/memoryGet.js +0 -3
  78. package/dist/plugin/tools/memoryIndexer.d.ts +0 -3
  79. package/dist/plugin/tools/memoryIndexer.js +0 -10
  80. package/dist/plugin/tools/memorySearch.d.ts +0 -31
  81. package/dist/plugin/tools/memorySearch.js +0 -79
  82. package/dist/plugin/tools/memoryWrite.d.ts +0 -8
  83. package/dist/plugin/tools/memoryWrite.js +0 -32
  84. package/dist/plugin/tools/retrospect.d.ts +0 -3
  85. package/dist/plugin/tools/retrospect.js +0 -3
  86. package/dist/plugin/tools/slashcommand.d.ts +0 -11
  87. package/dist/plugin/tools/slashcommand.js +0 -38
  88. package/dist/plugin/tools/squad.d.ts +0 -12
  89. package/dist/plugin/tools/squad.js +11 -83
  90. package/dist/plugin/tools/weave.d.ts +0 -6
  91. package/dist/plugin/tools/weave.js +0 -78
  92. package/dist/plugin/types.d.ts +0 -20
  93. package/dist/plugin/types.js +0 -7
  94. package/dist/retrospect/index.d.ts +0 -7
  95. package/dist/retrospect/index.js +0 -9
  96. package/dist/retrospect/mask-save.d.ts +0 -12
  97. package/dist/retrospect/mask-save.js +1 -80
  98. package/dist/retrospect/retrospect.d.ts +0 -18
  99. package/dist/retrospect/retrospect.js +0 -63
  100. package/dist/retrospect/strategies/base.d.ts +0 -15
  101. package/dist/retrospect/strategies/base.js +0 -7
  102. package/dist/retrospect/strategies/deep.d.ts +0 -12
  103. package/dist/retrospect/strategies/deep.js +0 -24
  104. package/dist/retrospect/strategies/index.d.ts +0 -12
  105. package/dist/retrospect/strategies/index.js +0 -12
  106. package/dist/retrospect/strategies/quick.d.ts +0 -12
  107. package/dist/retrospect/strategies/quick.js +0 -19
  108. package/dist/retrospect/strategies/standard.d.ts +0 -12
  109. package/dist/retrospect/strategies/standard.js +0 -15
  110. package/dist/retrospect/types.d.ts +0 -7
  111. package/dist/retrospect/types.js +0 -7
  112. package/dist/shared/config.d.ts +0 -105
  113. package/dist/shared/config.js +0 -33
  114. package/dist/shared/errors.d.ts +0 -18
  115. package/dist/shared/errors.js +0 -19
  116. package/dist/shared/generate-agents.d.ts +0 -69
  117. package/dist/shared/generate-agents.js +2 -86
  118. package/dist/shared/image.d.ts +0 -67
  119. package/dist/shared/image.js +6 -104
  120. package/dist/shared/index.d.ts +0 -5
  121. package/dist/shared/index.js +0 -7
  122. package/dist/shared/model-registry.d.ts +0 -72
  123. package/dist/shared/model-registry.js +5 -95
  124. package/dist/shared/types.d.ts +0 -15
  125. package/dist/shared/types.js +0 -3
  126. package/dist/shared-context/dag.d.ts +0 -105
  127. package/dist/shared-context/dag.js +3 -114
  128. package/dist/shared-context/index.d.ts +0 -5
  129. package/dist/shared-context/index.js +0 -15
  130. package/dist/shared-context/logger.d.ts +0 -37
  131. package/dist/shared-context/logger.js +0 -41
  132. package/dist/shared-context/parallel-executor.d.ts +0 -54
  133. package/dist/shared-context/parallel-executor.js +4 -56
  134. package/dist/shared-context/session.d.ts +0 -56
  135. package/dist/shared-context/session.js +0 -47
  136. package/dist/shared-context/squad.d.ts +0 -68
  137. package/dist/shared-context/squad.js +0 -63
  138. package/dist/shared-context/storage.d.ts +0 -132
  139. package/dist/shared-context/storage.js +0 -116
  140. package/dist/shared-context/task.d.ts +0 -120
  141. package/dist/shared-context/task.js +0 -152
  142. package/dist/shared-context/test/dag.test.js +9 -14
  143. package/dist/shared-context/test/logger.test.d.ts +0 -8
  144. package/dist/shared-context/test/logger.test.js +0 -52
  145. package/dist/shared-context/test/session.test.d.ts +0 -7
  146. package/dist/shared-context/test/session.test.js +0 -63
  147. package/dist/shared-context/test/squad.test.d.ts +0 -10
  148. package/dist/shared-context/test/squad.test.js +2 -68
  149. package/dist/shared-context/test/storage.test.d.ts +0 -8
  150. package/dist/shared-context/test/storage.test.js +0 -68
  151. package/dist/shared-context/test/task.test.d.ts +0 -7
  152. package/dist/shared-context/test/task.test.js +0 -54
  153. package/dist/shared-context/test/watchdog.test.d.ts +0 -7
  154. package/dist/shared-context/test/watchdog.test.js +3 -58
  155. package/dist/shared-context/types.d.ts +0 -215
  156. package/dist/shared-context/types.js +0 -125
  157. package/dist/shared-context/watchdog.d.ts +0 -127
  158. package/dist/shared-context/watchdog.js +0 -148
  159. package/dist/shared-context/worktree.d.ts +0 -68
  160. package/dist/shared-context/worktree.js +2 -34
  161. package/dist/verify/budget.d.ts +0 -29
  162. package/dist/verify/budget.js +0 -34
  163. package/dist/verify/critical-files.d.ts +0 -17
  164. package/dist/verify/critical-files.js +0 -37
  165. package/dist/verify/escalation.d.ts +0 -20
  166. package/dist/verify/escalation.js +0 -22
  167. package/dist/verify/index.d.ts +0 -5
  168. package/dist/verify/index.js +0 -11
  169. package/dist/verify/prompts.d.ts +0 -20
  170. package/dist/verify/prompts.js +0 -20
  171. package/dist/verify/types.d.ts +0 -26
  172. package/dist/verify/types.js +1 -12
  173. package/dist/verify/verifier.d.ts +0 -29
  174. package/dist/verify/verifier.js +0 -54
  175. package/dist/version.d.ts +1 -16
  176. package/dist/version.js +1 -16
  177. package/dist/weave/bridge.d.ts +0 -35
  178. package/dist/weave/bridge.js +0 -51
  179. package/dist/weave/environment/detector.d.ts +0 -6
  180. package/dist/weave/environment/detector.js +4 -45
  181. package/dist/weave/environment/index.d.ts +0 -19
  182. package/dist/weave/environment/index.js +1 -39
  183. package/dist/weave/environment/issues.d.ts +0 -35
  184. package/dist/weave/environment/issues.js +0 -59
  185. package/dist/weave/git.d.ts +0 -8
  186. package/dist/weave/git.js +0 -8
  187. package/dist/weave/index.d.ts +0 -13
  188. package/dist/weave/index.js +2 -28
  189. package/dist/weave/knowledge/global.d.ts +0 -39
  190. package/dist/weave/knowledge/global.js +2 -78
  191. package/dist/weave/loop.js +0 -3
  192. package/dist/weave/orchestrator.d.ts +0 -69
  193. package/dist/weave/orchestrator.js +1 -101
  194. package/dist/weave/phase-manager.d.ts +0 -64
  195. package/dist/weave/phase-manager.js +0 -89
  196. package/dist/weave/security/secret-scan.d.ts +0 -14
  197. package/dist/weave/security/secret-scan.js +0 -19
  198. package/dist/weave/stages/build.js +0 -15
  199. package/dist/weave/stages/execute.d.ts +0 -42
  200. package/dist/weave/stages/execute.js +4 -86
  201. package/dist/weave/stages/handoff.d.ts +0 -7
  202. package/dist/weave/stages/handoff.js +0 -43
  203. package/dist/weave/stages/index.d.ts +0 -3
  204. package/dist/weave/stages/index.js +0 -3
  205. package/dist/weave/stages/intake.d.ts +0 -8
  206. package/dist/weave/stages/intake.js +5 -65
  207. package/dist/weave/stages/map.d.ts +0 -1
  208. package/dist/weave/stages/openspec.d.ts +0 -1
  209. package/dist/weave/stages/plan.d.ts +0 -11
  210. package/dist/weave/stages/plan.js +1 -53
  211. package/dist/weave/stages/refine.d.ts +0 -7
  212. package/dist/weave/stages/refine.js +0 -7
  213. package/dist/weave/stages/research.d.ts +0 -6
  214. package/dist/weave/stages/research.js +0 -6
  215. package/dist/weave/stages/spec.d.ts +0 -12
  216. package/dist/weave/stages/spec.js +0 -17
  217. package/dist/weave/types.d.ts +0 -20
  218. package/dist/weave/types.js +0 -5
  219. package/dist/weave/verification/commands.d.ts +0 -12
  220. package/dist/weave/verification/commands.js +0 -19
  221. package/dist/weave/verification/index.d.ts +0 -6
  222. package/dist/weave/verification/index.js +1 -19
  223. package/dist/weave/verification/playwright.d.ts +0 -47
  224. package/dist/weave/verification/playwright.js +1 -90
  225. package/dist/weave/worktree.d.ts +0 -16
  226. package/dist/weave/worktree.js +0 -23
  227. package/dist/weave/yaml-repair.d.ts +0 -39
  228. package/dist/weave/yaml-repair.js +13 -116
  229. package/package.json +1 -1
@@ -1,11 +1,4 @@
1
- /**
2
- * Weave Tool for OpenCode Plugin
3
- *
4
- * Integrates Weave workflow into OpenCode as a tool.
5
- * Commands: design, craft, status
6
- */
7
1
  import { z } from 'zod';
8
- // Inline shim: tool() is just an identity function in @opencode-ai/plugin
9
2
  const tool = (input) => input;
10
3
  import { createHash } from 'node:crypto';
11
4
  import * as os from 'node:os';
@@ -39,9 +32,6 @@ import { acquireLoopOperatorLock, appendLoopEvent, createLoopRun, ensureLoopCont
39
32
  import { getEffectiveGdcConfig, runGdcMachineCommand, countGdcCheckIssues, getStatsNodeSummary, } from '../../weave/gdc.js';
40
33
  import { generatePoolAgentFilesFromConfig, writeDefaultRuntimeConfig, writeDefaultPluginConfig, } from '../../shared/generate-agents.js';
41
34
  import { resolveCommand, loadCommandsJson } from './command-registry.js';
42
- // ============================================================================
43
- // Tool Factory
44
- // ============================================================================
45
35
  export function createWeaveTool() {
46
36
  return {
47
37
  description: (() => {
@@ -145,7 +135,6 @@ export function createWeaveTool() {
145
135
  execute: async (args, context) => {
146
136
  const { command } = args;
147
137
  const basePath = context.worktree;
148
- // Resolve command aliases and deprecation
149
138
  const resolved = resolveCommand(command);
150
139
  if ('error' in resolved) {
151
140
  return `Error: ${resolved.error}`;
@@ -215,9 +204,6 @@ export function createWeaveTool() {
215
204
  },
216
205
  };
217
206
  }
218
- // ============================================================================
219
- // Command Handlers
220
- // ============================================================================
221
207
  function toWorkspaceRelative(basePath, filePath) {
222
208
  const rel = path.relative(basePath, filePath);
223
209
  if (!rel || rel.startsWith('..'))
@@ -1094,7 +1080,6 @@ async function migrateLegacyPlanIfNeeded(basePath, activePlan) {
1094
1080
  await unlink(legacyPlanPath);
1095
1081
  }
1096
1082
  catch {
1097
- // Non-fatal. Keep migrated plan and continue.
1098
1083
  }
1099
1084
  return {
1100
1085
  migrated: true,
@@ -1241,7 +1226,6 @@ async function handleInit(basePath) {
1241
1226
  lines.push('');
1242
1227
  lines.push(...gdcReport);
1243
1228
  lines.push('');
1244
- // Check global config
1245
1229
  const globalConfigPath = path.join(os.homedir(), '.config', 'opencode', 'maskweaver.config.json');
1246
1230
  if (!fs.existsSync(globalConfigPath)) {
1247
1231
  lines.push('');
@@ -1389,7 +1373,6 @@ async function handleApprovePlan(args, basePath) {
1389
1373
  }
1390
1374
  }
1391
1375
  catch {
1392
- // Optional note file.
1393
1376
  }
1394
1377
  }
1395
1378
  activePlan.planApproved = true;
@@ -1416,7 +1399,6 @@ async function handleDesign(args, basePath) {
1416
1399
  if (!docsPath) {
1417
1400
  return 'Error: docsPath is required for design command. Example: weave design docs/';
1418
1401
  }
1419
- // Step 1: Intake
1420
1402
  const resolvedDocsPath = resolveUnderBase(basePath, docsPath);
1421
1403
  const intakeResult = await intake({ docsPath: resolvedDocsPath });
1422
1404
  const researchResult = await writeResearchReport({
@@ -1425,7 +1407,6 @@ async function handleDesign(args, basePath) {
1425
1407
  basePath,
1426
1408
  projectName: projectName || 'My Project',
1427
1409
  });
1428
- // Check if there are questions
1429
1410
  if (intakeResult.questions.length > 0) {
1430
1411
  const lines = [];
1431
1412
  lines.push(researchResult.summary);
@@ -1449,7 +1430,6 @@ async function handleDesign(args, basePath) {
1449
1430
  lines.push('(또는 기본값으로 진행하려면 "기본값으로 진행해"라고 해주세요)');
1450
1431
  return lines.join('\n');
1451
1432
  }
1452
- // Step 2: Plan (if no questions or defaults accepted)
1453
1433
  const planResult = await plan({
1454
1434
  intake: intakeResult,
1455
1435
  projectName: projectName || 'My Project',
@@ -1508,7 +1488,6 @@ async function handlePrepare(args, basePath) {
1508
1488
  const intakeResult = await intake({ docsPath: resolvedDocsPath });
1509
1489
  const gdcPrepareSync = await runGdcPrepareSync(basePath);
1510
1490
  const normalizedPlanName = normalizePlanName(args.planName, projectName, resolvedDocsPath);
1511
- // Cache-aware skip: skip steps if artifacts already exist
1512
1491
  const researchPath = path.join(basePath, 'tasks', 'research.md');
1513
1492
  const specsDir = path.join(basePath, '.opencode', 'weave', 'specs');
1514
1493
  const plansDir = path.join(basePath, '.opencode', 'weave', 'plans');
@@ -1529,7 +1508,6 @@ async function handlePrepare(args, basePath) {
1529
1508
  return false;
1530
1509
  }
1531
1510
  })();
1532
- // Step 1: Research
1533
1511
  const researchResult = hasResearch
1534
1512
  ? {
1535
1513
  summary: `> ⏭️ Research skipped: \`${toWorkspaceRelative(basePath, researchPath)}\` already exists.`,
@@ -1541,7 +1519,6 @@ async function handlePrepare(args, basePath) {
1541
1519
  basePath,
1542
1520
  projectName: projectName || 'My Project',
1543
1521
  });
1544
- // Step 2: Spec (baseline)
1545
1522
  const specResult = hasSpec
1546
1523
  ? { summary: `> ⏭️ Spec skipped: existing artifact found in \`${toWorkspaceRelative(basePath, specsDir)}\`.` }
1547
1524
  : await createSpec({
@@ -1550,7 +1527,6 @@ async function handlePrepare(args, basePath) {
1550
1527
  specName: normalizedPlanName,
1551
1528
  basePath,
1552
1529
  });
1553
- // Step 3: Plan
1554
1530
  const planResult = hasPlan
1555
1531
  ? { summary: `> ⏭️ Plan skipped: existing artifact found in \`${toWorkspaceRelative(basePath, plansDir)}\`.` }
1556
1532
  : await plan({
@@ -1647,7 +1623,6 @@ async function handleFlow(args, basePath) {
1647
1623
  if (!phaseBeforeCraft) {
1648
1624
  return `Error: Phase not found: ${resolvedPhaseId}`;
1649
1625
  }
1650
- // Legacy plans may not have explicit tasks yet.
1651
1626
  if (!phaseBeforeCraft.tasks || phaseBeforeCraft.tasks.length === 0) {
1652
1627
  await manager.addTasks(resolvedPhaseId, generateDefaultPhaseTasks(phaseBeforeCraft));
1653
1628
  }
@@ -1770,9 +1745,6 @@ async function handleFlow(args, basePath) {
1770
1745
  });
1771
1746
  return lines.join('\n');
1772
1747
  }
1773
- // ============================================================================
1774
- // Handle Map — Codebase Analysis
1775
- // ============================================================================
1776
1748
  async function handleMap(args, basePath) {
1777
1749
  const lines = [];
1778
1750
  lines.push('## 🔍 Codebase Map');
@@ -1803,9 +1775,6 @@ async function handleMap(args, basePath) {
1803
1775
  lines.push('Next: `weave command=interview docsPath="doc"` to discuss the plan.');
1804
1776
  return lines.join('\n');
1805
1777
  }
1806
- // ============================================================================
1807
- // Handle Interview — Multi-step Question Asking
1808
- // ============================================================================
1809
1778
  async function handleInterview(args, basePath) {
1810
1779
  const docsPath = args.docsPath || 'docs';
1811
1780
  const lines = [];
@@ -1858,9 +1827,6 @@ async function handleInterview(args, basePath) {
1858
1827
  }
1859
1828
  return lines.join('\n');
1860
1829
  }
1861
- // ============================================================================
1862
- // Handle Build — Ralph-loop Autonomous Execution
1863
- // ============================================================================
1864
1830
  async function handleBuild(args, basePath) {
1865
1831
  const lines = [];
1866
1832
  lines.push('## 🏗️ Build');
@@ -1908,9 +1874,6 @@ async function handleBuild(args, basePath) {
1908
1874
  }
1909
1875
  return lines.join('\n');
1910
1876
  }
1911
- // ============================================================================
1912
- // Handle Build Resume
1913
- // ============================================================================
1914
1877
  async function handleBuildResume(args, basePath) {
1915
1878
  const lines = [];
1916
1879
  lines.push('## 🔄 Build Resume');
@@ -1957,10 +1920,8 @@ async function handleCraft(args, basePath) {
1957
1920
  return formatPlanApprovalRequired(basePath, activePlan);
1958
1921
  }
1959
1922
  if (!resolvedPhaseId) {
1960
- // Get next phase
1961
1923
  const manager = getPhaseManager(basePath);
1962
1924
  await manager.loadPlan();
1963
- // Show any recovery messages from auto-repair during load
1964
1925
  const recoveryMsgs = manager.getRecoveryMessages();
1965
1926
  recoveryPrefix = recoveryMsgs.length > 0
1966
1927
  ? `> **Auto-repair**: ${recoveryMsgs.join('; ')}\n\n`
@@ -1976,7 +1937,6 @@ async function handleCraft(args, basePath) {
1976
1937
  resolvedPhaseId = nextPhase.id;
1977
1938
  autoSelectedPhase = true;
1978
1939
  }
1979
- // Ensure tasks exist for legacy plans. (Old plans may have empty task arrays.)
1980
1940
  {
1981
1941
  const manager = getPhaseManager(basePath);
1982
1942
  await manager.loadPlan();
@@ -1988,7 +1948,6 @@ async function handleCraft(args, basePath) {
1988
1948
  await manager.addTasks(resolvedPhaseId, generateDefaultPhaseTasks(current));
1989
1949
  }
1990
1950
  }
1991
- // Prepare execution plan (validates, marks in_progress, generates plan)
1992
1951
  const events = [];
1993
1952
  const { plan: executionPlan } = await preparePhaseExecution({
1994
1953
  phaseId: resolvedPhaseId,
@@ -1996,7 +1955,6 @@ async function handleCraft(args, basePath) {
1996
1955
  onEvent: (event) => events.push(event),
1997
1956
  basePath,
1998
1957
  });
1999
- // Format the execution plan as markdown for the Mask Weaver
2000
1958
  const planMarkdown = formatExecutionPlan(executionPlan);
2001
1959
  const manager = getPhaseManager(basePath);
2002
1960
  await manager.loadPlan();
@@ -2086,14 +2044,11 @@ async function handleStatus(basePath) {
2086
2044
  const manager = getPhaseManager(basePath);
2087
2045
  const activePlan = await manager.loadPlan();
2088
2046
  const report = await generateStatusReport(basePath);
2089
- // Show any recovery messages from auto-repair
2090
2047
  const recoveryMsgs = manager.getRecoveryMessages();
2091
- // Add global knowledge stats
2092
2048
  const knowledge = new GlobalKnowledge();
2093
2049
  await knowledge.init();
2094
2050
  const stats = await knowledge.getStats();
2095
2051
  const lines = [];
2096
- // Show recovery warnings at the top
2097
2052
  if (recoveryMsgs.length > 0) {
2098
2053
  lines.push('### YAML Auto-Repair Report\n');
2099
2054
  for (const msg of recoveryMsgs) {
@@ -2247,7 +2202,6 @@ async function handleVerify(args, basePath) {
2247
2202
  return verification.report;
2248
2203
  }
2249
2204
  async function handleTroubleshoot(args) {
2250
- // Unified: record mode (absorbs old 'record' command)
2251
2205
  if (args.record) {
2252
2206
  if (!args.error || !args.solution) {
2253
2207
  return 'Error: error and solution are required when record=true. Example: weave command=troubleshoot record=true error="..." solution="..."';
@@ -2294,17 +2248,6 @@ async function handleRepair(basePath) {
2294
2248
  const { results, summary } = await manager.repairPlans();
2295
2249
  return summary;
2296
2250
  }
2297
- /**
2298
- * Handle `sync-agents` command.
2299
- *
2300
- * Reads maskweaver.config.json (project or global ~/.config/opencode/)
2301
- * and force-overwrites all dummy-human agent .md files in .opencode/agents/.
2302
- *
2303
- * Search order:
2304
- * 1. {projectDir}/maskweaver.config.json
2305
- * 2. {projectDir}/.opencode/maskweaver.config.json
2306
- * 3. ~/.config/opencode/maskweaver.config.json (user global)
2307
- */
2308
2251
  async function handleSyncAgents(basePath) {
2309
2252
  const agentsDir = path.join(basePath, '.opencode', 'agents');
2310
2253
  const result = generatePoolAgentFilesFromConfig(basePath, agentsDir, { force: true });
@@ -2344,18 +2287,10 @@ async function handleSyncAgents(basePath) {
2344
2287
  }
2345
2288
  return lines.join('\n');
2346
2289
  }
2347
- /**
2348
- * Handle `init-config` command.
2349
- *
2350
- * Creates default maskweaver.config.json (runtime config with pool template)
2351
- * and .opencode/maskweaver.json (plugin config) if they don't exist.
2352
- * Does NOT overwrite existing files.
2353
- */
2354
2290
  async function handleInitConfig(basePath) {
2355
2291
  const lines = [];
2356
2292
  lines.push('## 📝 Config Initialization');
2357
2293
  lines.push('');
2358
- // Create runtime config (maskweaver.config.json)
2359
2294
  const runtimePath = writeDefaultRuntimeConfig(basePath);
2360
2295
  if (runtimePath) {
2361
2296
  lines.push(`✅ Created runtime config: ${toWorkspaceRelative(basePath, runtimePath)}`);
@@ -2366,7 +2301,6 @@ async function handleInitConfig(basePath) {
2366
2301
  lines.push('⏭️ maskweaver.config.json already exists (skipped)');
2367
2302
  }
2368
2303
  lines.push('');
2369
- // Create plugin config (.opencode/maskweaver.json)
2370
2304
  const pluginPath = writeDefaultPluginConfig(basePath);
2371
2305
  if (pluginPath) {
2372
2306
  lines.push(`✅ Created plugin config: ${toWorkspaceRelative(basePath, pluginPath)}`);
@@ -2379,9 +2313,6 @@ async function handleInitConfig(basePath) {
2379
2313
  lines.push('> with your model pool, then run `weave sync-agents` in any project to apply it.');
2380
2314
  return lines.join('\n');
2381
2315
  }
2382
- // ============================================================================
2383
- // Unified Build Handler (absorbs build, build-resume, loop-*)
2384
- // ============================================================================
2385
2316
  async function handleBuildUnified(args, basePath) {
2386
2317
  const action = args.action || 'run';
2387
2318
  switch (action) {
@@ -2413,9 +2344,6 @@ async function handleBuildUnified(args, basePath) {
2413
2344
  return `Error: Unknown build action: ${action}. Available: run, status, stop, list, resume, sync.`;
2414
2345
  }
2415
2346
  }
2416
- // ============================================================================
2417
- // Agents Handler (absorbs sync-agents, init-config)
2418
- // ============================================================================
2419
2347
  async function handleAgents(args, basePath) {
2420
2348
  if (!args.sync && !args.init) {
2421
2349
  return 'Error: agents requires an action. Use `sync=true` to regenerate agent files, or `init=true` to create default config.';
@@ -3065,7 +2993,6 @@ async function handleApprove(args, basePath) {
3065
2993
  `Finalization blocked: verification failed for ${resolvedPhaseId}.`,
3066
2994
  ]);
3067
2995
  }
3068
- // If no commands detected, allow finalization but make it explicit.
3069
2996
  if (verification.results.length === 0) {
3070
2997
  await phaseManager.markAllTasksPassed(resolvedPhaseId);
3071
2998
  const result = await handleUserResponse(resolvedPhaseId, 'approve', undefined, basePath);
@@ -3082,7 +3009,6 @@ async function handleApprove(args, basePath) {
3082
3009
  shardSwitch ? 'Advanced to next shard.' : '',
3083
3010
  ].filter(Boolean));
3084
3011
  }
3085
- // Optional: commit during finalization
3086
3012
  if (commit) {
3087
3013
  try {
3088
3014
  await ensureGitRepo(basePath);
@@ -3121,7 +3047,6 @@ async function handleApprove(args, basePath) {
3121
3047
  const secretWarning = findings.length > 0
3122
3048
  ? formatSecretScanReport(findings)
3123
3049
  : null;
3124
- // Commit message fallback: Pn: Phase Name
3125
3050
  const phase = phaseManager.getPhase(resolvedPhaseId);
3126
3051
  const defaultMsg = phase ? `${phase.id}: ${phase.name}` : `${resolvedPhaseId}: complete`;
3127
3052
  const msg = (commitMessage && commitMessage.trim().length > 0)
@@ -3157,7 +3082,6 @@ async function handleApprove(args, basePath) {
3157
3082
  ]);
3158
3083
  }
3159
3084
  }
3160
- // Passed with results: include report in approval output.
3161
3085
  {
3162
3086
  await phaseManager.markAllTasksPassed(resolvedPhaseId);
3163
3087
  }
@@ -3320,7 +3244,6 @@ async function syncWorkflowArtifacts(basePath, manager, options) {
3320
3244
  await writeFile(todoPath, `${lines.join('\n')}\n`, 'utf-8');
3321
3245
  }
3322
3246
  catch {
3323
- // Non-fatal: artifact sync should never break workflow execution.
3324
3247
  }
3325
3248
  }
3326
3249
  function sanitizeLessonText(input, maxLength = 240) {
@@ -3363,7 +3286,6 @@ async function appendWorkflowLesson(basePath, lesson) {
3363
3286
  await writeFile(lessonsPath, `${current.trimEnd()}\n\n${entry}`, 'utf-8');
3364
3287
  }
3365
3288
  catch {
3366
- // Non-fatal: lesson capture should not block workflow execution.
3367
3289
  }
3368
3290
  }
3369
3291
  function resolveUnderBase(basePath, inputPath) {
@@ -1,32 +1,12 @@
1
- /**
2
- * Plugin Types
3
- *
4
- * Shared types for Maskweaver plugin tools
5
- *
6
- * Based on @opencode-ai/plugin tool definitions.
7
- */
8
1
  import type { z } from 'zod';
9
- /**
10
- * Minimal context required by Maskweaver tool factories.
11
- * SDK provides richer context, but factories only need worktree.
12
- */
13
2
  export interface ToolContext {
14
3
  worktree: string;
15
4
  }
16
- /**
17
- * Tool factory interface for creating OpenCode tools
18
- */
19
5
  export interface ToolFactory {
20
- /** Tool description shown to LLM */
21
6
  description: string;
22
- /** Zod schema for argument validation */
23
7
  args: z.ZodType<any>;
24
- /** Execute function that returns string result */
25
8
  execute: (args: any, context: ToolContext) => Promise<string>;
26
9
  }
27
- /**
28
- * Standard tool response format
29
- */
30
10
  export interface ToolResponse<T = unknown> {
31
11
  success: boolean;
32
12
  data?: T;
@@ -1,8 +1 @@
1
- /**
2
- * Plugin Types
3
- *
4
- * Shared types for Maskweaver plugin tools
5
- *
6
- * Based on @opencode-ai/plugin tool definitions.
7
- */
8
1
  export {};
@@ -1,10 +1,3 @@
1
- /**
2
- * Retrospect Package
3
- *
4
- * 회고 및 가면 관리 시스템
5
- *
6
- * "Export only what matters" - Kent Beck
7
- */
8
1
  export type { RetrospectTrigger, RetrospectDepth, MaskUsageRecord, RetrospectInput, RetrospectResult, } from './types.js';
9
2
  export type { RetrospectStrategy } from './strategies/base.js';
10
3
  export { selectStrategy, QuickRetrospectStrategy, StandardRetrospectStrategy, DeepRetrospectStrategy, } from './strategies/index.js';
@@ -1,12 +1,3 @@
1
- /**
2
- * Retrospect Package
3
- *
4
- * 회고 및 가면 관리 시스템
5
- *
6
- * "Export only what matters" - Kent Beck
7
- */
8
1
  export { selectStrategy, QuickRetrospectStrategy, StandardRetrospectStrategy, DeepRetrospectStrategy, } from './strategies/index.js';
9
- // Core functions
10
2
  export { performRetrospect, getMemoryPath, getDbPath } from './retrospect.js';
11
- // Mask save
12
3
  export { saveMask } from './mask-save.js';
@@ -1,10 +1,3 @@
1
- /**
2
- * Mask Save Logic
3
- *
4
- * 효과적인 가면을 MASKS.md에 저장
5
- *
6
- * "Clean code reads like well-written prose" - Kent Beck
7
- */
8
1
  interface MaskSaveInput {
9
2
  name: string;
10
3
  expertise: string;
@@ -21,10 +14,5 @@ interface MaskSaveResult {
21
14
  effectivenessScore?: number;
22
15
  message: string;
23
16
  }
24
- /**
25
- * 가면 저장
26
- *
27
- * "Make each function tell a story" - Kent Beck
28
- */
29
17
  export declare function saveMask(basePath: string, input: MaskSaveInput): MaskSaveResult;
30
18
  export type { MaskSaveInput, MaskSaveResult };
@@ -1,21 +1,8 @@
1
- /**
2
- * Mask Save Logic
3
- *
4
- * 효과적인 가면을 MASKS.md에 저장
5
- *
6
- * "Clean code reads like well-written prose" - Kent Beck
7
- */
8
1
  import { join } from 'path';
9
2
  import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
10
3
  import { getMemoryPath } from './retrospect.js';
11
- // ============================================================================
12
- // Constants
13
- // ============================================================================
14
4
  const EFFECTIVENESS_NEW_SCORE_WEIGHT = 0.3;
15
5
  const CUSTOM_SECTION_HEADER = '## 커스텀 가면';
16
- // ============================================================================
17
- // Date Formatting
18
- // ============================================================================
19
6
  function formatTimestamp() {
20
7
  const now = new Date();
21
8
  const year = now.getFullYear();
@@ -25,36 +12,19 @@ function formatTimestamp() {
25
12
  const minute = String(now.getMinutes()).padStart(2, '0');
26
13
  return `${year}-${month}-${day} ${hour}:${minute}`;
27
14
  }
28
- // ============================================================================
29
- // Effectiveness Score Calculation
30
- // ============================================================================
31
- /**
32
- * 이동 평균으로 효과성 점수 계산
33
- *
34
- * "The simplest thing that could possibly work" - Kent Beck
35
- */
36
15
  function calculateMovingAverageScore(currentScore, newScore, weight = EFFECTIVENESS_NEW_SCORE_WEIGHT) {
37
16
  if (currentScore === 0) {
38
17
  return newScore;
39
18
  }
40
19
  const updatedScore = currentScore * (1 - weight) + newScore * weight;
41
- return Math.round(updatedScore * 10) / 10; // 소수점 첫째 자리까지
20
+ return Math.round(updatedScore * 10) / 10;
42
21
  }
43
- // ============================================================================
44
- // Markdown Parsing
45
- // ============================================================================
46
- /**
47
- * 이름을 비교 가능한 형태로 정규화
48
- */
49
22
  function normalizeNameForComparison(name) {
50
23
  return name
51
24
  .toLowerCase()
52
25
  .replace(/\s+/g, '')
53
26
  .replace(/[()]/g, '');
54
27
  }
55
- /**
56
- * MASKS.md에서 특정 가면 섹션을 찾습니다.
57
- */
58
28
  function findMaskSection(content, maskName) {
59
29
  const lines = content.split('\n');
60
30
  const normalizedTarget = normalizeNameForComparison(maskName);
@@ -63,23 +33,19 @@ function findMaskSection(content, maskName) {
63
33
  let currentScore = 0;
64
34
  for (let i = 0; i < lines.length; i++) {
65
35
  const line = lines[i];
66
- // ### 가면명 형식 감지
67
36
  if (line.startsWith('### ')) {
68
- // 이전 가면 섹션 종료 체크
69
37
  if (currentMaskStart !== -1) {
70
38
  const normalizedCurrent = normalizeNameForComparison(currentMaskName);
71
39
  if (normalizedCurrent === normalizedTarget) {
72
40
  return { start: currentMaskStart, end: i - 1, score: currentScore };
73
41
  }
74
42
  }
75
- // 새 가면 섹션 시작
76
43
  currentMaskStart = i;
77
44
  const withoutPrefix = line.replace(/^###\s*/, '');
78
45
  const nameMatch = withoutPrefix.match(/^([^(]+)/);
79
46
  currentMaskName = nameMatch ? nameMatch[1].trim() : withoutPrefix.trim();
80
47
  currentScore = 0;
81
48
  }
82
- // 효과성 점수 추출
83
49
  if (currentMaskStart !== -1 && line.includes('**효과성 점수**')) {
84
50
  const colonIndex = line.indexOf(':');
85
51
  if (colonIndex !== -1) {
@@ -88,7 +54,6 @@ function findMaskSection(content, maskName) {
88
54
  }
89
55
  }
90
56
  }
91
- // 마지막 가면 체크
92
57
  if (currentMaskStart !== -1) {
93
58
  const normalizedCurrent = normalizeNameForComparison(currentMaskName);
94
59
  if (normalizedCurrent === normalizedTarget) {
@@ -97,12 +62,6 @@ function findMaskSection(content, maskName) {
97
62
  }
98
63
  return null;
99
64
  }
100
- // ============================================================================
101
- // Markdown Generation
102
- // ============================================================================
103
- /**
104
- * 새 가면 섹션 마크다운 생성
105
- */
106
65
  function generateNewMaskSection(input) {
107
66
  const timestamp = formatTimestamp();
108
67
  const usageRecord = input.usageNote
@@ -118,29 +77,22 @@ function generateNewMaskSection(input) {
118
77
  ${usageRecord}
119
78
  `;
120
79
  }
121
- /**
122
- * 기존 가면 섹션 업데이트
123
- */
124
80
  function updateExistingMask(content, section, newScore, usageNote) {
125
81
  const lines = content.split('\n');
126
82
  const timestamp = formatTimestamp();
127
83
  const newUsageRecord = usageNote
128
84
  ? ` - ${timestamp} (점수: ${newScore}) - ${usageNote}`
129
85
  : ` - ${timestamp} (점수: ${newScore})`;
130
- // 효과성 점수 업데이트
131
86
  const updatedScore = calculateMovingAverageScore(section.score, newScore);
132
87
  const sectionLines = lines.slice(section.start, section.end + 1);
133
88
  const result = [];
134
89
  let usageRecordInserted = false;
135
90
  for (const line of sectionLines) {
136
- // 효과성 점수 라인 업데이트
137
91
  if (line.includes('**효과성 점수**')) {
138
92
  result.push(`- **효과성 점수**: ${updatedScore}`);
139
93
  }
140
- // 사용 기록 라인 찾기
141
94
  else if (line.includes('**사용 기록**')) {
142
95
  result.push(line);
143
- // 바로 다음에 새 기록 추가
144
96
  result.push(newUsageRecord);
145
97
  usageRecordInserted = true;
146
98
  }
@@ -148,43 +100,28 @@ function updateExistingMask(content, section, newScore, usageNote) {
148
100
  result.push(line);
149
101
  }
150
102
  }
151
- // 사용 기록 섹션이 없으면 마지막에 추가
152
103
  if (!usageRecordInserted) {
153
104
  result.push(`- **사용 기록**: `);
154
105
  result.push(newUsageRecord);
155
106
  }
156
- // 전체 파일 재구성
157
107
  const before = lines.slice(0, section.start);
158
108
  const after = lines.slice(section.end + 1);
159
109
  return [...before, ...result, ...after].join('\n');
160
110
  }
161
- /**
162
- * 새 가면 추가
163
- */
164
111
  function addNewMask(content, input) {
165
112
  const newSection = generateNewMaskSection(input);
166
- // 커스텀 가면 섹션 찾기
167
113
  const customSectionIndex = content.indexOf(CUSTOM_SECTION_HEADER);
168
114
  if (customSectionIndex !== -1) {
169
- // 커스텀 섹션 바로 다음에 추가
170
115
  const insertPosition = customSectionIndex + CUSTOM_SECTION_HEADER.length;
171
116
  const afterHeader = content.slice(insertPosition);
172
117
  const beforeHeader = content.slice(0, insertPosition);
173
118
  return `${beforeHeader}\n\n${newSection}${afterHeader}`;
174
119
  }
175
- // 커스텀 섹션이 없으면 파일 끝에 추가
176
120
  return `${content}\n${CUSTOM_SECTION_HEADER}\n\n${newSection}`;
177
121
  }
178
- // ============================================================================
179
- // File Operations
180
- // ============================================================================
181
- /**
182
- * MASKS.md 파일 읽기
183
- */
184
122
  function readMasksFile(basePath) {
185
123
  const masksPath = getMemoryPath('masks', basePath);
186
124
  if (!existsSync(masksPath)) {
187
- // 기본 템플릿 반환
188
125
  return `# 가면 라이브러리 (Mask Library)
189
126
 
190
127
  이 파일은 가면술사가 사용하는 가면들의 정의와 효과성을 기록합니다.
@@ -202,9 +139,6 @@ ${CUSTOM_SECTION_HEADER}
202
139
  }
203
140
  return readFileSync(masksPath, 'utf-8');
204
141
  }
205
- /**
206
- * MASKS.md 파일 쓰기
207
- */
208
142
  function writeMasksFile(basePath, content) {
209
143
  const masksPath = getMemoryPath('masks', basePath);
210
144
  const dir = join(basePath, '.opencode', 'memory');
@@ -213,32 +147,19 @@ function writeMasksFile(basePath, content) {
213
147
  }
214
148
  writeFileSync(masksPath, content, 'utf-8');
215
149
  }
216
- // ============================================================================
217
- // Main Function
218
- // ============================================================================
219
- /**
220
- * 가면 저장
221
- *
222
- * "Make each function tell a story" - Kent Beck
223
- */
224
150
  export function saveMask(basePath, input) {
225
151
  try {
226
- // 1. MASKS.md 읽기
227
152
  let content = readMasksFile(basePath);
228
- // 2. 해당 가면이 있는지 확인
229
153
  const existingSection = findMaskSection(content, input.name);
230
154
  let action;
231
155
  if (existingSection) {
232
- // 3a. 기존 가면 업데이트
233
156
  content = updateExistingMask(content, existingSection, input.effectivenessScore, input.usageNote);
234
157
  action = 'updated';
235
158
  }
236
159
  else {
237
- // 3b. 새 가면 추가
238
160
  content = addNewMask(content, input);
239
161
  action = 'created';
240
162
  }
241
- // 4. 파일 저장
242
163
  writeMasksFile(basePath, content);
243
164
  return {
244
165
  success: true,
@@ -1,23 +1,5 @@
1
- /**
2
- * Retrospect Core
3
- *
4
- * 회고 시스템의 메인 로직
5
- *
6
- * "Each function has one clear purpose" - Kent Beck
7
- */
8
1
  import type { RetrospectInput, RetrospectResult } from './types.js';
9
- /**
10
- * 메모리 경로 반환
11
- */
12
2
  declare function getMemoryPath(type: string, basePath: string): string;
13
- /**
14
- * DB 경로 반환
15
- */
16
3
  declare function getDbPath(basePath: string): string;
17
- /**
18
- * 회고 수행
19
- *
20
- * "Make it work, make it right, make it fast" - Kent Beck
21
- */
22
4
  export declare function performRetrospect(basePath: string, input: RetrospectInput): RetrospectResult;
23
5
  export { getMemoryPath, getDbPath };