@ai-content-space/loopx 0.1.9 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/AGENTS.md +50 -0
  2. package/README.md +59 -446
  3. package/README.zh-CN.md +59 -457
  4. package/docs/loopx/design/loopx-skill-suite-v1-design.md +73 -0
  5. package/docs/loopx/plans/loopx-skill-suite-v1-implementation.md +77 -0
  6. package/package.json +5 -2
  7. package/plugins/loopx/.codex-plugin/plugin.json +4 -4
  8. package/plugins/loopx/scripts/plugin-install.test.mjs +20 -20
  9. package/plugins/loopx/skills/clarify/SKILL.md +38 -311
  10. package/plugins/loopx/skills/debug/SKILL.md +1 -1
  11. package/plugins/loopx/skills/exec/SKILL.md +71 -0
  12. package/plugins/loopx/skills/finish/SKILL.md +254 -0
  13. package/plugins/loopx/skills/fix-review/SKILL.md +216 -0
  14. package/plugins/loopx/skills/go-style/SKILL.md +1 -1
  15. package/plugins/loopx/skills/kratos/SKILL.md +1 -1
  16. package/plugins/loopx/skills/plan/SKILL.md +136 -258
  17. package/plugins/loopx/skills/refactor-plan/SKILL.md +71 -0
  18. package/plugins/loopx/skills/review/SKILL.md +72 -105
  19. package/plugins/loopx/skills/review/code-reviewer.md +168 -0
  20. package/plugins/loopx/skills/spec/DESIGN_SPEC_TEMPLATE.md +323 -0
  21. package/plugins/loopx/skills/spec/SKILL.md +76 -0
  22. package/plugins/loopx/skills/subagent-exec/SKILL.md +282 -0
  23. package/plugins/loopx/skills/subagent-exec/agents/openai.yaml +3 -0
  24. package/plugins/loopx/skills/subagent-exec/code-quality-reviewer-prompt.md +25 -0
  25. package/plugins/loopx/skills/subagent-exec/codex-subagents.md +37 -0
  26. package/plugins/loopx/skills/subagent-exec/implementer-prompt.md +113 -0
  27. package/plugins/loopx/skills/subagent-exec/spec-reviewer-prompt.md +61 -0
  28. package/plugins/loopx/skills/tdd/SKILL.md +1 -1
  29. package/plugins/loopx/skills/verify/SKILL.md +1 -1
  30. package/scripts/claude-workflow-hook.mjs +109 -0
  31. package/scripts/codex-workflow-hook.mjs +2 -5
  32. package/scripts/install-skills.mjs +3 -3
  33. package/scripts/verify-skills.mjs +32 -1
  34. package/skills/RESOLVER.md +26 -17
  35. package/skills/clarify/SKILL.md +38 -311
  36. package/skills/debug/SKILL.md +1 -1
  37. package/skills/exec/SKILL.md +71 -0
  38. package/skills/finish/SKILL.md +254 -0
  39. package/skills/fix-review/SKILL.md +216 -0
  40. package/skills/go-style/SKILL.md +1 -1
  41. package/skills/kratos/SKILL.md +1 -1
  42. package/skills/plan/SKILL.md +136 -258
  43. package/skills/refactor-plan/SKILL.md +71 -0
  44. package/skills/review/SKILL.md +72 -105
  45. package/skills/review/code-reviewer.md +168 -0
  46. package/skills/spec/DESIGN_SPEC_TEMPLATE.md +323 -0
  47. package/skills/spec/SKILL.md +76 -0
  48. package/skills/subagent-exec/SKILL.md +282 -0
  49. package/skills/subagent-exec/agents/openai.yaml +3 -0
  50. package/skills/subagent-exec/code-quality-reviewer-prompt.md +25 -0
  51. package/skills/subagent-exec/codex-subagents.md +37 -0
  52. package/skills/subagent-exec/implementer-prompt.md +113 -0
  53. package/skills/subagent-exec/spec-reviewer-prompt.md +61 -0
  54. package/skills/tdd/SKILL.md +1 -1
  55. package/skills/verify/SKILL.md +1 -1
  56. package/src/autopilot-runtime.mjs +1 -1
  57. package/src/cli.mjs +79 -5
  58. package/src/context-manifest.mjs +2 -2
  59. package/src/html-views.mjs +457 -95
  60. package/src/install-discovery.mjs +210 -6
  61. package/src/next-skill.mjs +2 -4
  62. package/src/plan-runtime.mjs +572 -93
  63. package/src/runtime-maintenance.mjs +60 -16
  64. package/src/workflow.mjs +989 -65
  65. package/templates/architecture.md +58 -16
  66. package/templates/development-plan.md +42 -12
  67. package/plugins/loopx/skills/archive/SKILL.md +0 -55
  68. package/plugins/loopx/skills/autopilot/SKILL.md +0 -93
  69. package/plugins/loopx/skills/build/SKILL.md +0 -228
  70. package/skills/archive/SKILL.md +0 -55
  71. package/skills/autopilot/SKILL.md +0 -93
  72. package/skills/build/SKILL.md +0 -228
@@ -39,6 +39,8 @@ const CHANGE_ARTIFACT_FILE_MAP = {
39
39
  graph: 'artifact-graph.json',
40
40
  };
41
41
 
42
+ const PLAN_ARTIFACTS = ['plan.md', 'architecture.md', 'development-plan.md', 'test-plan.md'];
43
+
42
44
  function normalizeSlug(raw) {
43
45
  return String(raw || '')
44
46
  .trim()
@@ -47,6 +49,44 @@ function normalizeSlug(raw) {
47
49
  .replace(/^-+|-+$/g, '');
48
50
  }
49
51
 
52
+ function containsChineseText(text) {
53
+ const chineseChars = text.match(/[\u3400-\u9fff]/g) || [];
54
+ const latinChars = text.match(/[A-Za-z]/g) || [];
55
+ const signalChars = chineseChars.length + latinChars.length;
56
+ if (signalChars === 0) {
57
+ return false;
58
+ }
59
+ return chineseChars.length >= 40 || (chineseChars.length >= 8 && chineseChars.length / signalChars >= 0.2);
60
+ }
61
+
62
+ async function legacyPlanArtifactBlockers(workflowRoot) {
63
+ const blockers = [];
64
+ for (const name of PLAN_ARTIFACTS) {
65
+ const path = join(workflowRoot, name);
66
+ const key = name
67
+ .replace(/\.md$/, '')
68
+ .replace(/-([a-z])/g, (_, char) => char.toUpperCase());
69
+ if (!existsSync(path)) {
70
+ blockers.push(`missing_plan_artifact_${key}`);
71
+ continue;
72
+ }
73
+ const text = await readFile(path, 'utf8');
74
+ if (!containsChineseText(text)) {
75
+ blockers.push(`plan_artifact_not_chinese_${key}`);
76
+ }
77
+ }
78
+ if (!existsSync(join(workflowRoot, 'requirement-traceability.md'))) {
79
+ blockers.push('missing_requirement_traceability');
80
+ }
81
+ if (!existsSync(join(workflowRoot, 'plan-delegation-decision.md'))) {
82
+ blockers.push('missing_plan_delegation_decision');
83
+ }
84
+ if (!existsSync(join(workflowRoot, 'plan-reviews'))) {
85
+ blockers.push('missing_plan_review_artifacts');
86
+ }
87
+ return blockers;
88
+ }
89
+
50
90
  export function resolveLoopxRoot(cwd) {
51
91
  return join(resolve(cwd), '.loopx');
52
92
  }
@@ -329,27 +369,29 @@ function createMigratedWorkflowBaseState(slug, legacyState, change) {
329
369
  async function migrateLegacyWorkflowState(cwd, slug, workflowRoot, legacyState) {
330
370
  const change = await findActiveChangeForWorkflow(cwd, slug);
331
371
  const reviewState = await inferReviewState(workflowRoot);
332
- const canonicalPlanPath = join(resolveLoopxRoot(cwd), 'plans', `prd-${slug}.md`);
372
+ const canonicalPlanPath = join(resolveLoopxRoot(cwd), 'plans', `requirements-snapshot-${slug}.md`);
373
+ const legacyCanonicalPlanPath = join(resolveLoopxRoot(cwd), 'plans', `prd-${slug}.md`);
333
374
  const canonicalTestSpecPath = join(resolveLoopxRoot(cwd), 'plans', `test-spec-${slug}.md`);
334
375
  const baseState = createMigratedWorkflowBaseState(slug, legacyState, change);
335
- const planDocsComplete = ['plan.md', 'architecture.md', 'development-plan.md', 'test-plan.md']
336
- .every((name) => existsSync(join(workflowRoot, name)));
376
+ const planBlockers = await legacyPlanArtifactBlockers(workflowRoot);
377
+ const planDocsComplete = planBlockers.length === 0;
337
378
  const executionRecordStatus = await inferExecutionStatus(workflowRoot);
338
- const planState = planDocsComplete ? {
379
+ const planState = PLAN_ARTIFACTS.some((name) => existsSync(join(workflowRoot, name))) ? {
339
380
  current_stage: STAGES.PLAN,
340
- stage_status: 'awaiting-approval',
341
- plan_package_status: 'complete',
381
+ stage_status: planDocsComplete ? 'awaiting-approval' : 'blocked',
382
+ plan_package_status: planDocsComplete ? 'complete' : 'partial',
342
383
  plan_current_iteration: 1,
343
- plan_principles_resolved: true,
344
- plan_options_reviewed: true,
345
- plan_architect_review_status: 'complete',
346
- plan_critic_verdict: 'approve',
347
- plan_acceptance_criteria_testable: true,
348
- plan_verification_steps_resolved: true,
349
- plan_execution_inputs_resolved: true,
350
- plan_docs_status: 'complete',
384
+ plan_principles_resolved: planDocsComplete,
385
+ plan_options_reviewed: planDocsComplete,
386
+ plan_architect_review_status: planDocsComplete ? 'complete' : 'not-started',
387
+ plan_critic_verdict: planDocsComplete ? 'approve' : 'none',
388
+ plan_acceptance_criteria_testable: planDocsComplete,
389
+ plan_verification_steps_resolved: planDocsComplete,
390
+ plan_execution_inputs_resolved: planDocsComplete,
391
+ plan_docs_status: planDocsComplete ? 'complete' : 'partial',
392
+ plan_blockers: planBlockers,
351
393
  approval: {
352
- plan: APPROVAL_STATES.APPROVED,
394
+ plan: planDocsComplete ? APPROVAL_STATES.APPROVED : APPROVAL_STATES.NOT_REQUESTED,
353
395
  build: APPROVAL_STATES.NOT_REQUESTED,
354
396
  review: APPROVAL_STATES.NOT_REQUESTED,
355
397
  rollback: APPROVAL_STATES.NOT_REQUESTED,
@@ -381,7 +423,9 @@ async function migrateLegacyWorkflowState(cwd, slug, workflowRoot, legacyState)
381
423
  schema_version: WORKFLOW_SCHEMA_VERSION,
382
424
  slug,
383
425
  clarify_profile: legacyState.clarify_profile || legacyState.profile || 'standard',
384
- plan_artifact_path: existsSync(canonicalPlanPath) ? canonicalPlanPath : join(workflowRoot, 'plan.md'),
426
+ plan_artifact_path: existsSync(canonicalPlanPath)
427
+ ? canonicalPlanPath
428
+ : (existsSync(legacyCanonicalPlanPath) ? legacyCanonicalPlanPath : join(workflowRoot, 'plan.md')),
385
429
  test_spec_artifact_path: existsSync(canonicalTestSpecPath) ? canonicalTestSpecPath : join(workflowRoot, 'test-plan.md'),
386
430
  execution_record_status: executionRecordStatus,
387
431
  ...(reviewState || {}),