@ai-content-space/loopx 0.2.3 → 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.
- package/README.md +106 -10
- package/README.zh-CN.md +106 -10
- 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
- package/docs/loopx/memory/2026-06-09-stale-archive-hook-guidance.md +15 -0
- package/docs/loopx/memory/README.md +25 -0
- package/docs/loopx/plans/2026-06-08-finish-audit-change-window.md +933 -0
- package/docs/loopx/plans/2026-06-08-finish-learning-audit.md +410 -0
- package/docs/loopx/plans/2026-06-09-cli-onboarding-install-surface.md +1277 -0
- package/docs/loopx/specs/installation.md +33 -0
- package/package.json +18 -2
- package/plugins/loopx/.codex-plugin/plugin.json +1 -1
- package/plugins/loopx/skills/clarify/SKILL.md +1 -1
- package/plugins/loopx/skills/debug/SKILL.md +1 -1
- package/plugins/loopx/skills/doc-readability/SKILL.md +222 -0
- package/plugins/loopx/skills/doc-readability/references/prd.md +269 -0
- package/plugins/loopx/skills/exec/SKILL.md +11 -1
- package/plugins/loopx/skills/final-review/SKILL.md +1 -1
- package/plugins/loopx/skills/finish/SKILL.md +39 -7
- package/plugins/loopx/skills/fix-review/SKILL.md +1 -1
- package/plugins/loopx/skills/go-style/SKILL.md +1 -1
- package/plugins/loopx/skills/kratos/SKILL.md +1 -1
- package/plugins/loopx/skills/plan/SKILL.md +1 -1
- package/plugins/loopx/skills/refactor-plan/SKILL.md +1 -1
- package/plugins/loopx/skills/review/SKILL.md +1 -1
- package/plugins/loopx/skills/spec/SKILL.md +1 -1
- package/plugins/loopx/skills/subagent-exec/SKILL.md +13 -1
- package/plugins/loopx/skills/tdd/SKILL.md +1 -1
- package/plugins/loopx/skills/verify/SKILL.md +1 -1
- package/scripts/claude-workflow-hook.mjs +50 -1
- package/scripts/codex-workflow-hook.mjs +33 -12
- package/scripts/install-skills.mjs +58 -3
- package/scripts/verify-skills.mjs +83 -7
- package/skills/RESOLVER.md +3 -1
- package/skills/clarify/SKILL.md +1 -1
- package/skills/debug/SKILL.md +1 -1
- package/skills/doc-readability/SKILL.md +222 -0
- package/skills/doc-readability/references/prd.md +269 -0
- package/skills/exec/SKILL.md +11 -1
- package/skills/final-review/SKILL.md +1 -1
- package/skills/finish/SKILL.md +39 -7
- package/skills/fix-review/SKILL.md +1 -1
- package/skills/go-style/SKILL.md +1 -1
- package/skills/kratos/SKILL.md +1 -1
- package/skills/plan/SKILL.md +1 -1
- package/skills/refactor-plan/SKILL.md +1 -1
- package/skills/review/SKILL.md +1 -1
- package/skills/spec/SKILL.md +1 -1
- package/skills/subagent-exec/SKILL.md +13 -1
- package/skills/tdd/SKILL.md +1 -1
- package/skills/verify/SKILL.md +1 -1
- package/src/cli.mjs +473 -86
- package/src/finish-runtime.mjs +1184 -0
- package/src/install-discovery.mjs +38 -0
- package/src/next-skill.mjs +8 -10
- package/src/workflow.mjs +19 -26
- package/skills/deepsearch/SKILL.md +0 -38
|
@@ -28,6 +28,7 @@ const LOOPX_SKILLS = [
|
|
|
28
28
|
'debug',
|
|
29
29
|
'tdd',
|
|
30
30
|
'verify',
|
|
31
|
+
'doc-readability',
|
|
31
32
|
'go-style',
|
|
32
33
|
'kratos',
|
|
33
34
|
];
|
|
@@ -824,10 +825,46 @@ async function mergeClaudeHookSettings(env = process.env, options = {}) {
|
|
|
824
825
|
return { settingsPath, hookPath, command };
|
|
825
826
|
}
|
|
826
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
|
+
|
|
827
863
|
export async function installSkillsForTargets(env = process.env, options = {}) {
|
|
828
864
|
const requestedTargets = Array.isArray(options.targets) && options.targets.length > 0
|
|
829
865
|
? options.targets
|
|
830
866
|
: ['codex', 'claude'];
|
|
867
|
+
assertInstallTargetOptions(requestedTargets, options);
|
|
831
868
|
const results = {};
|
|
832
869
|
for (const target of requestedTargets) {
|
|
833
870
|
if (target === 'codex') {
|
|
@@ -866,6 +903,7 @@ export async function verifyInstallTargets(env = process.env, options = {}) {
|
|
|
866
903
|
const requestedTargets = Array.isArray(options.targets) && options.targets.length > 0
|
|
867
904
|
? options.targets
|
|
868
905
|
: ['codex', 'claude'];
|
|
906
|
+
assertInstallTargetOptions(requestedTargets, options);
|
|
869
907
|
const results = {};
|
|
870
908
|
for (const target of requestedTargets) {
|
|
871
909
|
if (target === 'codex') {
|
package/src/next-skill.mjs
CHANGED
|
@@ -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
|
-
|
|
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 ->
|
|
526
|
+
'`clarify -> spec? -> plan -> (subagent-exec | exec) -> final-review -> fix-review? -> finish`',
|
|
527
527
|
'',
|
|
528
|
-
'##
|
|
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
|
|
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 ? '
|
|
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
|
-
?
|
|
3138
|
-
:
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
?
|
|
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', '
|
|
3534
|
-
preferred_surface: ['clarify', 'plan', '
|
|
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: ['
|
|
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.
|