@ai-content-space/loopx 0.2.1 → 0.2.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/README.md +6 -1
- package/README.zh-CN.md +6 -1
- package/docs/loopx/design/loopx-skill-suite-v1-design.md +4 -3
- package/package.json +1 -1
- 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/exec/SKILL.md +7 -2
- package/plugins/loopx/skills/final-review/SKILL.md +89 -0
- package/plugins/loopx/skills/final-review/final-reviewer.md +135 -0
- package/plugins/loopx/skills/finish/SKILL.md +8 -1
- package/plugins/loopx/skills/fix-review/SKILL.md +1 -1
- package/plugins/loopx/skills/go-style/SKILL.md +8 -2
- package/plugins/loopx/skills/kratos/SKILL.md +7 -1
- package/plugins/loopx/skills/plan/SKILL.md +3 -3
- 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 +7 -6
- package/plugins/loopx/skills/subagent-exec/agents/openai.yaml +2 -2
- package/plugins/loopx/skills/subagent-exec/codex-subagents.md +1 -1
- package/plugins/loopx/skills/tdd/SKILL.md +1 -1
- package/plugins/loopx/skills/verify/SKILL.md +1 -1
- package/scripts/codex-workflow-hook.mjs +36 -5
- package/skills/RESOLVER.md +7 -4
- package/skills/clarify/SKILL.md +1 -1
- package/skills/debug/SKILL.md +1 -1
- package/skills/exec/SKILL.md +7 -2
- package/skills/final-review/SKILL.md +89 -0
- package/skills/final-review/final-reviewer.md +135 -0
- package/skills/finish/SKILL.md +8 -1
- package/skills/fix-review/SKILL.md +1 -1
- package/skills/go-style/SKILL.md +8 -2
- package/skills/kratos/SKILL.md +7 -1
- package/skills/plan/SKILL.md +3 -3
- 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 +7 -6
- package/skills/subagent-exec/agents/openai.yaml +2 -2
- package/skills/subagent-exec/codex-subagents.md +1 -1
- package/skills/tdd/SKILL.md +1 -1
- package/skills/verify/SKILL.md +1 -1
- package/src/build-stop-gate.mjs +1 -1
- package/src/cli.mjs +5 -1
- package/src/install-discovery.mjs +1 -28
- package/src/next-skill.mjs +46 -5
- package/src/workflow.mjs +4 -4
|
@@ -21,6 +21,7 @@ const LOOPX_SKILLS = [
|
|
|
21
21
|
'subagent-exec',
|
|
22
22
|
'exec',
|
|
23
23
|
'review',
|
|
24
|
+
'final-review',
|
|
24
25
|
'fix-review',
|
|
25
26
|
'finish',
|
|
26
27
|
'refactor-plan',
|
|
@@ -30,18 +31,6 @@ const LOOPX_SKILLS = [
|
|
|
30
31
|
'go-style',
|
|
31
32
|
'kratos',
|
|
32
33
|
];
|
|
33
|
-
const LOOPX_LEGACY_SKILLS = [
|
|
34
|
-
'build',
|
|
35
|
-
'autopilot',
|
|
36
|
-
'archive',
|
|
37
|
-
'writing-plans',
|
|
38
|
-
'executing-plans',
|
|
39
|
-
'subagent-driven-development',
|
|
40
|
-
'requesting-code-review',
|
|
41
|
-
'receiving-code-review',
|
|
42
|
-
'finishing-a-development-branch',
|
|
43
|
-
'request-refactor-plan',
|
|
44
|
-
];
|
|
45
34
|
const LOOPX_INSTALLATION_IDENTITY = 'loopx';
|
|
46
35
|
const LOOPX_MANAGED_SCRIPT_ITEMS = [
|
|
47
36
|
{
|
|
@@ -452,20 +441,6 @@ async function removeStaleOwnedInstall(currentRow) {
|
|
|
452
441
|
await removeInstalledSkill(currentRow.installedPath);
|
|
453
442
|
}
|
|
454
443
|
|
|
455
|
-
async function pruneLegacyLoopxOwnedSkills(nextData, env = process.env) {
|
|
456
|
-
const pruned = [];
|
|
457
|
-
for (const skillName of LOOPX_LEGACY_SKILLS) {
|
|
458
|
-
const row = nextData.skills?.[skillName];
|
|
459
|
-
if (!isLoopxOwnedIdentity(skillName, row, env)) {
|
|
460
|
-
continue;
|
|
461
|
-
}
|
|
462
|
-
await removeStaleOwnedInstall(row);
|
|
463
|
-
delete nextData.skills[skillName];
|
|
464
|
-
pruned.push({ skillName, installedPath: row.installedPath });
|
|
465
|
-
}
|
|
466
|
-
return pruned;
|
|
467
|
-
}
|
|
468
|
-
|
|
469
444
|
async function removeInstalledFile(path) {
|
|
470
445
|
if (!existsSync(path)) {
|
|
471
446
|
return;
|
|
@@ -667,7 +642,6 @@ export async function installBundledSkills(env = process.env, options = {}) {
|
|
|
667
642
|
const nextData = jsonClone(data);
|
|
668
643
|
nextData.version = nextData.version || 3;
|
|
669
644
|
nextData.skills = nextData.skills || {};
|
|
670
|
-
const pruned = await pruneLegacyLoopxOwnedSkills(nextData, env);
|
|
671
645
|
const baselinePath = getTemplateBaselinePath(env);
|
|
672
646
|
const existingBaseline = await readTemplateBaseline(baselinePath);
|
|
673
647
|
const baselineItemsByPath = new Map((existingBaseline?.items || []).map((item) => [templateItemKey(item), item]));
|
|
@@ -766,7 +740,6 @@ export async function installBundledSkills(env = process.env, options = {}) {
|
|
|
766
740
|
installed,
|
|
767
741
|
conflicts,
|
|
768
742
|
skipped,
|
|
769
|
-
pruned,
|
|
770
743
|
templateGovernance,
|
|
771
744
|
inspection: await inspectInstallState(env),
|
|
772
745
|
};
|
package/src/next-skill.mjs
CHANGED
|
@@ -2,7 +2,6 @@ export function nextSkillCommand(state) {
|
|
|
2
2
|
if (!state || !state.slug) {
|
|
3
3
|
return null;
|
|
4
4
|
}
|
|
5
|
-
const reviewBuildCommand = `$build --from-review .loopx/workflows/${state.slug}/review-report.md`;
|
|
6
5
|
if (state.current_stage === 'clarify'
|
|
7
6
|
&& state.clarify_current_round > 0
|
|
8
7
|
&& state.unresolved_ambiguity_count === 0
|
|
@@ -28,7 +27,7 @@ export function nextSkillCommand(state) {
|
|
|
28
27
|
return null;
|
|
29
28
|
}
|
|
30
29
|
if (state.current_stage === 'plan' && Array.isArray(state.plan_blockers) && state.plan_blockers.length === 0) {
|
|
31
|
-
return `$
|
|
30
|
+
return `$subagent-exec .loopx/plans/requirements-snapshot-${state.slug}.md`;
|
|
32
31
|
}
|
|
33
32
|
if (state.current_stage === 'build'
|
|
34
33
|
&& state.stage_status === 'awaiting-approval'
|
|
@@ -48,13 +47,13 @@ export function nextSkillCommand(state) {
|
|
|
48
47
|
|| state.approval?.build === 'requested'
|
|
49
48
|
|| state.approval?.build === 'approved'
|
|
50
49
|
)) {
|
|
51
|
-
return
|
|
50
|
+
return null;
|
|
52
51
|
}
|
|
53
52
|
if (state.current_stage === 'review'
|
|
54
53
|
&& state.review_verdict === 'request-changes'
|
|
55
54
|
&& state.requested_transition === 'review->build'
|
|
56
55
|
&& state.approval?.build === 'approved') {
|
|
57
|
-
return
|
|
56
|
+
return null;
|
|
58
57
|
}
|
|
59
58
|
if (state.current_stage === 'review'
|
|
60
59
|
&& state.review_verdict === 'request-changes'
|
|
@@ -71,20 +70,62 @@ export function nextSkillCommand(state) {
|
|
|
71
70
|
return null;
|
|
72
71
|
}
|
|
73
72
|
|
|
73
|
+
export function nextCliCommand(state) {
|
|
74
|
+
if (!state || !state.slug) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
if (state.stage_status === 'awaiting-approval'
|
|
78
|
+
&& state.current_stage === 'plan'
|
|
79
|
+
&& Array.isArray(state.plan_blockers)
|
|
80
|
+
&& state.plan_blockers.length === 0) {
|
|
81
|
+
return `loopx build .loopx/plans/requirements-snapshot-${state.slug}.md`;
|
|
82
|
+
}
|
|
83
|
+
if (state.current_stage === 'review'
|
|
84
|
+
&& state.review_verdict === 'request-changes'
|
|
85
|
+
&& state.rollback_target === 'build'
|
|
86
|
+
&& (
|
|
87
|
+
state.pending_user_decision === 'review->build'
|
|
88
|
+
|| state.requested_transition === 'review->build'
|
|
89
|
+
|| state.approval?.build === 'requested'
|
|
90
|
+
|| state.approval?.build === 'approved'
|
|
91
|
+
)) {
|
|
92
|
+
return `loopx build --from-review .loopx/workflows/${state.slug}/review-report.md`;
|
|
93
|
+
}
|
|
94
|
+
if (state.current_stage === 'review'
|
|
95
|
+
&& state.review_verdict === 'request-changes'
|
|
96
|
+
&& state.requested_transition === 'review->build'
|
|
97
|
+
&& state.approval?.build === 'approved') {
|
|
98
|
+
return `loopx build --from-review .loopx/workflows/${state.slug}/review-report.md`;
|
|
99
|
+
}
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
|
|
74
103
|
export function nextSkillHint(state) {
|
|
75
104
|
const command = nextSkillCommand(state);
|
|
76
105
|
if (!command) {
|
|
77
106
|
return null;
|
|
78
107
|
}
|
|
79
|
-
return `Next: ${command}`;
|
|
108
|
+
return `Next skill: ${command}`;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function nextCliHint(state) {
|
|
112
|
+
const command = nextCliCommand(state);
|
|
113
|
+
if (!command) {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
return `Next CLI: ${command}`;
|
|
80
117
|
}
|
|
81
118
|
|
|
82
119
|
export function withNextSkill(payload, state) {
|
|
83
120
|
const nextCommand = nextSkillCommand(state);
|
|
84
121
|
const nextHint = nextSkillHint(state);
|
|
122
|
+
const cliCommand = nextCliCommand(state);
|
|
123
|
+
const cliHint = nextCliHint(state);
|
|
85
124
|
return {
|
|
86
125
|
...payload,
|
|
87
126
|
next_skill_command: nextCommand,
|
|
88
127
|
next_skill_hint: nextHint,
|
|
128
|
+
next_cli_command: cliCommand,
|
|
129
|
+
next_cli_hint: cliHint,
|
|
89
130
|
};
|
|
90
131
|
}
|
package/src/workflow.mjs
CHANGED
|
@@ -118,7 +118,7 @@ function reviewReportArtifactPath(slug) {
|
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
function reviewReworkBuildCommand(slug) {
|
|
121
|
-
return
|
|
121
|
+
return `loopx build --from-review ${reviewReportArtifactPath(slug)}`;
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
function nowIso() {
|
|
@@ -4203,7 +4203,7 @@ export async function buildStage(cwd, slug, options = {}) {
|
|
|
4203
4203
|
active_delegation_count: delegationLedger?.active_blocking_count || 0,
|
|
4204
4204
|
completion_audit_path: displayPath(cwd, completionAuditPath),
|
|
4205
4205
|
completion_audit_status: completionAudit?.status || 'pending',
|
|
4206
|
-
next_action: 'Continue
|
|
4206
|
+
next_action: 'Continue loopx build execution and gather fresh implementation evidence.',
|
|
4207
4207
|
completion_signal: 'Build may stop only after execution-record.md is complete and build -> review handoff readiness is reached, or after a real blocker is recorded.',
|
|
4208
4208
|
});
|
|
4209
4209
|
current = await adapter.executeLanes({
|
|
@@ -4271,7 +4271,7 @@ export async function buildStage(cwd, slug, options = {}) {
|
|
|
4271
4271
|
completion_audit_status: completionAudit.status,
|
|
4272
4272
|
next_action: blockers.length === 0
|
|
4273
4273
|
? 'Verify execution evidence and prepare build -> review handoff.'
|
|
4274
|
-
: 'Continue
|
|
4274
|
+
: 'Continue loopx build to resolve blockers before review handoff.',
|
|
4275
4275
|
completion_signal: 'Build may stop only after execution-record.md is complete and build -> review handoff readiness is reached, or after a real blocker is recorded.',
|
|
4276
4276
|
});
|
|
4277
4277
|
const writtenSupportPaths = await writeBuildSupportArtifacts(root, current, noDeslop, {
|
|
@@ -4373,7 +4373,7 @@ export async function buildStage(cwd, slug, options = {}) {
|
|
|
4373
4373
|
active_delegation_count: delegationLedger?.active_blocking_count || 0,
|
|
4374
4374
|
completion_audit_path: displayPath(cwd, completionAuditPath),
|
|
4375
4375
|
completion_audit_status: completionAudit?.status || (finalBlocked ? 'blocked' : 'passed'),
|
|
4376
|
-
next_action: finalBlocked ? 'Run
|
|
4376
|
+
next_action: finalBlocked ? 'Run loopx build again after resolving recorded blockers.' : 'Approve build -> review and run $review.',
|
|
4377
4377
|
completion_signal: finalBlocked ? 'Build is stopped because real blockers remain recorded.' : 'execution-record.md is complete and build -> review handoff is ready.',
|
|
4378
4378
|
execution_record_status: next.execution_record_status,
|
|
4379
4379
|
execution_record_path: artifactPath(root, 'execution-record.md'),
|