@ai-content-space/loopx 0.2.4 → 0.2.7

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 (53) hide show
  1. package/README.md +106 -10
  2. package/README.zh-CN.md +106 -10
  3. package/docs/loopx/design/finish/345/255/246/344/271/240/345/256/241/350/256/241/351/234/200/346/261/202/350/256/276/350/256/241/346/226/207/346/241/243.md +707 -0
  4. package/docs/loopx/memory/2026-06-09-stale-archive-hook-guidance.md +15 -0
  5. package/docs/loopx/memory/README.md +25 -0
  6. package/docs/loopx/plans/2026-06-08-finish-audit-change-window.md +933 -0
  7. package/docs/loopx/plans/2026-06-08-finish-learning-audit.md +410 -0
  8. package/docs/loopx/plans/2026-06-09-cli-onboarding-install-surface.md +1277 -0
  9. package/docs/loopx/specs/installation.md +33 -0
  10. package/package.json +18 -2
  11. package/plugins/loopx/.codex-plugin/plugin.json +1 -1
  12. package/plugins/loopx/skills/clarify/SKILL.md +1 -1
  13. package/plugins/loopx/skills/debug/SKILL.md +1 -1
  14. package/plugins/loopx/skills/doc-readability/SKILL.md +1 -1
  15. package/plugins/loopx/skills/exec/SKILL.md +11 -1
  16. package/plugins/loopx/skills/final-review/SKILL.md +1 -1
  17. package/plugins/loopx/skills/finish/SKILL.md +39 -7
  18. package/plugins/loopx/skills/fix-review/SKILL.md +1 -1
  19. package/plugins/loopx/skills/go-style/SKILL.md +1 -1
  20. package/plugins/loopx/skills/kratos/SKILL.md +1 -1
  21. package/plugins/loopx/skills/plan/SKILL.md +1 -1
  22. package/plugins/loopx/skills/refactor-plan/SKILL.md +1 -1
  23. package/plugins/loopx/skills/review/SKILL.md +1 -1
  24. package/plugins/loopx/skills/spec/SKILL.md +1 -1
  25. package/plugins/loopx/skills/subagent-exec/SKILL.md +13 -1
  26. package/plugins/loopx/skills/tdd/SKILL.md +1 -1
  27. package/plugins/loopx/skills/verify/SKILL.md +1 -1
  28. package/scripts/claude-workflow-hook.mjs +50 -1
  29. package/scripts/codex-workflow-hook.mjs +33 -12
  30. package/scripts/install-skills.mjs +58 -3
  31. package/scripts/verify-skills.mjs +83 -7
  32. package/skills/clarify/SKILL.md +1 -1
  33. package/skills/debug/SKILL.md +1 -1
  34. package/skills/doc-readability/SKILL.md +1 -1
  35. package/skills/exec/SKILL.md +11 -1
  36. package/skills/final-review/SKILL.md +1 -1
  37. package/skills/finish/SKILL.md +39 -7
  38. package/skills/fix-review/SKILL.md +1 -1
  39. package/skills/go-style/SKILL.md +1 -1
  40. package/skills/kratos/SKILL.md +1 -1
  41. package/skills/plan/SKILL.md +1 -1
  42. package/skills/refactor-plan/SKILL.md +1 -1
  43. package/skills/review/SKILL.md +1 -1
  44. package/skills/spec/SKILL.md +1 -1
  45. package/skills/subagent-exec/SKILL.md +13 -1
  46. package/skills/tdd/SKILL.md +1 -1
  47. package/skills/verify/SKILL.md +1 -1
  48. package/src/cli.mjs +473 -86
  49. package/src/finish-runtime.mjs +1184 -0
  50. package/src/install-discovery.mjs +37 -0
  51. package/src/next-skill.mjs +8 -10
  52. package/src/workflow.mjs +19 -26
  53. package/skills/deepsearch/SKILL.md +0 -38
@@ -825,10 +825,46 @@ async function mergeClaudeHookSettings(env = process.env, options = {}) {
825
825
  return { settingsPath, hookPath, command };
826
826
  }
827
827
 
828
+ function assertInstallTargetOptions(requestedTargets, options = {}) {
829
+ const targets = new Set(requestedTargets);
830
+ if (options.dir && targets.has('codex') && targets.has('claude')) {
831
+ throw new Error('install_custom_dir_requires_single_target');
832
+ }
833
+ }
834
+
835
+ export async function inspectInstallTargets(env = process.env, options = {}) {
836
+ const requestedTargets = Array.isArray(options.targets) && options.targets.length > 0
837
+ ? options.targets
838
+ : ['codex', 'claude'];
839
+ assertInstallTargetOptions(requestedTargets, options);
840
+ const results = {};
841
+ for (const target of requestedTargets) {
842
+ if (target === 'codex') {
843
+ results.codex = await inspectInstallState(codexInstallEnv({
844
+ ...env,
845
+ LOOPX_INSTALL_CUSTOM_DIR: options.dir,
846
+ }));
847
+ continue;
848
+ }
849
+ if (target === 'claude') {
850
+ results.claude = await inspectInstallState(claudeInstallEnv(env, options));
851
+ continue;
852
+ }
853
+ throw new Error(`unknown_install_target:${target}`);
854
+ }
855
+ return {
856
+ ok: true,
857
+ dryRun: true,
858
+ targets: requestedTargets,
859
+ results,
860
+ };
861
+ }
862
+
828
863
  export async function installSkillsForTargets(env = process.env, options = {}) {
829
864
  const requestedTargets = Array.isArray(options.targets) && options.targets.length > 0
830
865
  ? options.targets
831
866
  : ['codex', 'claude'];
867
+ assertInstallTargetOptions(requestedTargets, options);
832
868
  const results = {};
833
869
  for (const target of requestedTargets) {
834
870
  if (target === 'codex') {
@@ -867,6 +903,7 @@ export async function verifyInstallTargets(env = process.env, options = {}) {
867
903
  const requestedTargets = Array.isArray(options.targets) && options.targets.length > 0
868
904
  ? options.targets
869
905
  : ['codex', 'claude'];
906
+ assertInstallTargetOptions(requestedTargets, options);
870
907
  const results = {};
871
908
  for (const target of requestedTargets) {
872
909
  if (target === 'codex') {
@@ -12,16 +12,8 @@ export function nextSkillCommand(state) {
12
12
  return `$plan ${state.slug}`;
13
13
  }
14
14
  if (state.current_stage === 'done'
15
- && state.completion_confirmed === true
16
- && state.archive_status !== 'archived') {
17
- return `$archive ${state.slug}`;
18
- }
19
- if (state.current_stage === 'review'
20
- && state.review_verdict === 'approve'
21
- && state.pending_user_decision === 'review->done'
22
- && ['requested', 'approved'].includes(state.approval?.complete)
23
- && state.archive_status !== 'archived') {
24
- return `$archive ${state.slug}`;
15
+ && state.completion_confirmed === true) {
16
+ return '$finish';
25
17
  }
26
18
  if (state.stage_status !== 'awaiting-approval') {
27
19
  return null;
@@ -80,6 +72,12 @@ export function nextCliCommand(state) {
80
72
  && state.plan_blockers.length === 0) {
81
73
  return `loopx build .loopx/plans/requirements-snapshot-${state.slug}.md`;
82
74
  }
75
+ if (state.current_stage === 'review'
76
+ && state.review_verdict === 'approve'
77
+ && state.pending_user_decision === 'review->done'
78
+ && ['requested', 'approved'].includes(state.approval?.complete)) {
79
+ return `loopx approve ${state.slug} --from review --to done`;
80
+ }
83
81
  if (state.current_stage === 'review'
84
82
  && state.review_verdict === 'request-changes'
85
83
  && state.rollback_target === 'build'
package/src/workflow.mjs CHANGED
@@ -523,25 +523,22 @@ function buildWorkspaceReadme() {
523
523
  '',
524
524
  '## Default Flow',
525
525
  '',
526
- '`clarify -> plan -> build -> review -> done`',
526
+ '`clarify -> spec? -> plan -> (subagent-exec | exec) -> final-review -> fix-review? -> finish`',
527
527
  '',
528
- '## Runtime Commands',
528
+ '## User Commands',
529
529
  '',
530
530
  '- `loopx init [--slug <slug>]`',
531
- '- `loopx clarify <slug>`',
532
- '- `loopx approve <slug> --from <stage> --to <stage>`',
533
- '- `loopx plan <slug>`',
534
- '- `loopx build <slug>`',
535
- '- `loopx review <slug> [--reviewer <name>]`',
536
- '- `loopx archive <slug>`',
537
- '- `loopx autopilot <slug> [--reviewer <name>]`',
531
+ '- `loopx clarify <slug> [--standard|--deep] [--json]`',
538
532
  '- `loopx render [slug|--all]`',
539
533
  '- `loopx status [slug] [--json]`',
534
+ '- `loopx next <slug> [--json]`',
540
535
  '- `loopx setup-context`',
541
536
  '- `loopx doctor`',
542
537
  '- `loopx migrate`',
543
538
  '- `loopx repair-install`',
544
539
  '',
540
+ 'Advanced runtime commands are hidden from the normal path. Use `loopx help advanced` only when debugging runtime compatibility paths.',
541
+ '',
545
542
  '## Document Boundaries',
546
543
  '',
547
544
  'User-facing documents to watch:',
@@ -549,7 +546,7 @@ function buildWorkspaceReadme() {
549
546
  '- `workflows/<slug>/spec.md`',
550
547
  '- `workflows/<slug>/plan.md`, `architecture.md`, `development-plan.md`, and `test-plan.md`',
551
548
  '- `workflows/<slug>/execution-record.md` and `review-report.md`',
552
- '- `views/index.html` and `workflows/<slug>/view/index.html` after `loopx plan` or `loopx render`',
549
+ '- `views/index.html` and `workflows/<slug>/view/index.html` after planning or `loopx render`',
553
550
  '',
554
551
  'Documents users may read and edit as workflow fact sources:',
555
552
  '',
@@ -3029,7 +3026,7 @@ function buildCurrentEvidenceChain(state, readiness = buildReadiness(state), aut
3029
3026
  evidence.push(evidenceEntry(
3030
3027
  'review_approved',
3031
3028
  'Review verdict is approve.',
3032
- authorization.done.authorized ? 'Archive can consume the approved review -> done transition before syncing specs.' : 'Completion still requires explicit review -> done authorization.',
3029
+ authorization.done.authorized ? 'Approved review can proceed with explicit review -> done authorization before $finish records branch disposition and learning audit.' : 'Completion still requires explicit review -> done authorization before $finish.',
3033
3030
  ));
3034
3031
  }
3035
3032
  if (state.archive_status === 'archived' && state.spec_sync_status === 'synced') {
@@ -3134,8 +3131,8 @@ function recommendedAction(state, legacy = false) {
3134
3131
  switch (state.current_stage) {
3135
3132
  case STAGES.CLARIFY:
3136
3133
  return state.approval.plan === APPROVAL_STATES.APPROVED
3137
- ? 'Run loopx plan to consume the approved clarify -> plan transition.'
3138
- : `Resolve ambiguity in ${state.clarify_profile ?? 'standard'} clarify mode and approve clarify -> plan.`;
3134
+ ? `Follow $plan ${state.slug}.`
3135
+ : 'Finish clarification, then follow $plan when ready.';
3139
3136
  case STAGES.PLAN:
3140
3137
  if (Array.isArray(state.plan_blockers) && state.plan_blockers.length > 0) {
3141
3138
  return 'Run loopx plan to continue the planning review loop until architect, critic, and planning artifact blockers are cleared.';
@@ -3152,7 +3149,9 @@ function recommendedAction(state, legacy = false) {
3152
3149
  : 'Approve build -> review when execution-record.md is complete.';
3153
3150
  case STAGES.REVIEW:
3154
3151
  if (state.review_verdict === 'approve') {
3155
- return 'Run loopx archive; archive consumes the pending review -> done completion transition before syncing specs.';
3152
+ return state.approval.complete === APPROVAL_STATES.APPROVED
3153
+ ? 'Run $finish to complete branch disposition and learning audit.'
3154
+ : 'Approve review -> done, then run $finish to complete branch disposition and learning audit.';
3156
3155
  }
3157
3156
  if (state.review_verdict === 'request-changes') {
3158
3157
  if (state.requested_transition === TRANSITIONS.REVIEW_TO_BUILD && state.approval.build === APPROVAL_STATES.APPROVED) {
@@ -3177,10 +3176,7 @@ function recommendedAction(state, legacy = false) {
3177
3176
  if (state.autopilot_current_phase && state.autopilot_current_phase !== 'none' && state.autopilot_completed) {
3178
3177
  return 'Autopilot run is complete.';
3179
3178
  }
3180
- if (state.archive_status !== 'archived') {
3181
- return 'Run loopx archive to sync the approved change delta into long-lived specs.';
3182
- }
3183
- return 'Workflow is complete.';
3179
+ return 'Workflow is complete. Run $finish if branch disposition and learning audit have not been recorded.';
3184
3180
  default:
3185
3181
  return 'Run loopx clarify to start a workflow.';
3186
3182
  }
@@ -3353,11 +3349,8 @@ function nextCommandForRollbackTarget(slug, target) {
3353
3349
  if (target === 'none') {
3354
3350
  return [
3355
3351
  'Next:',
3356
- `$archive ${slug}`,
3357
- '',
3358
- 'CLI-only equivalent:',
3359
3352
  `loopx approve ${slug} --from review --to done`,
3360
- `loopx archive ${slug}`,
3353
+ '$finish',
3361
3354
  ].join('\n');
3362
3355
  }
3363
3356
  return [
@@ -3370,7 +3363,7 @@ function nextCommandForRollbackTarget(slug, target) {
3370
3363
  function reviewUserMessageZh({ slug, verdict, rollbackTarget, findings }) {
3371
3364
  const label = reviewVerdictLabel(verdict);
3372
3365
  const next = verdict === 'APPROVE'
3373
- ? `下一步:直接归档;archive 会先消费 pending 的 review -> done 完成态。\n${nextCommandForRollbackTarget(slug, 'none')}`
3366
+ ? `下一步:批准 review -> done,然后执行 finish 完成分支处置和学习审计。\n${nextCommandForRollbackTarget(slug, 'none')}`
3374
3367
  : `下一步:按审查发现处理,并${rollbackTargetLabel(rollbackTarget)}。\n${nextCommandForRollbackTarget(slug, rollbackTarget)}`;
3375
3368
  const findingText = Array.isArray(findings) && findings.length > 0 ? findings.join(';') : '无额外发现。';
3376
3369
  return `Review 结果:${slug} ${label}。审查发现:${findingText} ${next}`;
@@ -3530,8 +3523,8 @@ export async function initWorkspace(cwd, { slug, agentDelegation = {} } = {}) {
3530
3523
  schema_version: WORKSPACE_SCHEMA_VERSION,
3531
3524
  tool: 'loopx',
3532
3525
  product_contract: 'skill-first-v1',
3533
- default_flow: ['clarify', 'plan', 'build', 'review', 'done', 'archive'],
3534
- preferred_surface: ['clarify', 'plan', 'build', 'review', 'archive', 'autopilot'],
3526
+ default_flow: ['clarify', 'plan', 'subagent-exec', 'final-review', 'finish'],
3527
+ preferred_surface: ['clarify', 'plan', 'subagent-exec', 'review', 'final-review', 'fix-review', 'finish'],
3535
3528
  source_of_truth_policy: projectConventions.source_of_truth_policy,
3536
3529
  project_conventions: {
3537
3530
  existing_ai_rules: projectConventions.existing_ai_rules,
@@ -4736,7 +4729,7 @@ export async function reviewStage(cwd, slug, { reviewer = 'independent-reviewer'
4736
4729
  verdict: reviewInput.verdict,
4737
4730
  reviewMessageZh: reviewMessage,
4738
4731
  evidenceManifest: reviewInput.evidenceManifest,
4739
- followUps: ['执行 $archive;archive 会消费 pending 的 review -> done 完成态。'],
4732
+ followUps: ['批准 review -> done,然后执行 $finish 完成分支处置和学习审计。'],
4740
4733
  });
4741
4734
  } catch (error) {
4742
4735
  journalWarning = error instanceof Error ? error.message : String(error);
@@ -1,38 +0,0 @@
1
- ---
2
- name: deepsearch
3
- description: Thorough codebase search
4
- ---
5
-
6
- # Deep Search Mode
7
-
8
- [DEEPSEARCH MODE ACTIVATED]
9
-
10
- ## Objective
11
-
12
- Perform thorough search of the codebase for the specified query, pattern, or concept.
13
-
14
- ## Search Strategy
15
-
16
- 1. **Broad Search**
17
- - Search for exact matches
18
- - Search for related terms and variations
19
- - Check common locations (components, utils, services, hooks)
20
-
21
- 2. **Deep Dive**
22
- - Read files with matches
23
- - Check imports/exports to find connections
24
- - Follow the trail (what imports this? what does this import?)
25
-
26
- 3. **Synthesize**
27
- - Map out where the concept is used
28
- - Identify the main implementation
29
- - Note related functionality
30
-
31
- ## Output Format
32
-
33
- - **Primary Locations** (main implementations)
34
- - **Related Files** (dependencies, consumers)
35
- - **Usage Patterns** (how it's used across the codebase)
36
- - **Key Insights** (patterns, conventions, gotchas)
37
-
38
- Focus on being comprehensive but concise. Cite file paths and line numbers.