archondev 2.19.30 → 2.19.32
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 +2 -0
- package/dist/index.js +122 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -123,6 +123,8 @@ pnpm exec tsx scripts/init-governance-db.ts
|
|
|
123
123
|
- You can paste multi‑line requests into interactive prompts; Archon captures them as a single response.
|
|
124
124
|
- Proposal approvals like `approve plan` now bind to the pending proposal context in chat mode.
|
|
125
125
|
- Governance boundary/path checks in execute now steer with actionable guidance and set atoms to `BLOCKED` rather than hard failing.
|
|
126
|
+
- Analysis-first requests now return recommendations first and require explicit `create atom` before task creation.
|
|
127
|
+
- Chat execution now requires explicit execute intent (for example, `execute atom`) instead of generic `continue`.
|
|
126
128
|
|
|
127
129
|
**Tip:** Use `archon plan --edit` to adjust title and acceptance criteria before planning.
|
|
128
130
|
**Web Checks:** If Archon detects a web project, it prompts to run A11y/SEO/GEO checks and stores your preference in `.archon/config.yaml`.
|
package/dist/index.js
CHANGED
|
@@ -3701,6 +3701,10 @@ async function handleAgentConversationInput(cwd, input) {
|
|
|
3701
3701
|
return true;
|
|
3702
3702
|
}
|
|
3703
3703
|
if (wantsProposalBeforeExecution(input)) {
|
|
3704
|
+
if (shouldDoAnalysisBeforeAtom(input)) {
|
|
3705
|
+
await provideAnalysisFirstPlan(cwd, input);
|
|
3706
|
+
return true;
|
|
3707
|
+
}
|
|
3704
3708
|
await showProposalForApproval(input);
|
|
3705
3709
|
return true;
|
|
3706
3710
|
}
|
|
@@ -3780,16 +3784,70 @@ Showing latest planned atom (${latest.externalId})...
|
|
|
3780
3784
|
await show2(latest.externalId);
|
|
3781
3785
|
}
|
|
3782
3786
|
function isPlanApprovalDirective(input) {
|
|
3783
|
-
const normalized = input
|
|
3784
|
-
|
|
3787
|
+
const normalized = normalizeDirectiveInput(input);
|
|
3788
|
+
if (!normalized) return false;
|
|
3789
|
+
const directApprovals = /* @__PURE__ */ new Set([
|
|
3790
|
+
"approve",
|
|
3791
|
+
"approve plan",
|
|
3792
|
+
"approved",
|
|
3793
|
+
"yes",
|
|
3794
|
+
"yes proceed",
|
|
3795
|
+
"y",
|
|
3796
|
+
"ok",
|
|
3797
|
+
"okay",
|
|
3798
|
+
"proceed",
|
|
3799
|
+
"go ahead",
|
|
3800
|
+
"continue",
|
|
3801
|
+
"do it",
|
|
3802
|
+
"sounds good",
|
|
3803
|
+
"looks good"
|
|
3804
|
+
]);
|
|
3805
|
+
if (directApprovals.has(normalized)) return true;
|
|
3806
|
+
if (normalized.startsWith("yes ")) return true;
|
|
3807
|
+
if (/\b(approve|approved)\b/.test(normalized)) return true;
|
|
3808
|
+
const hasProceedSignal = /\b(go ahead|proceed|continue|do it|move forward|keep going)\b/.test(normalized);
|
|
3809
|
+
const hasPlanReference = /\b(plan|proposal|that|this|capsule|capsules)\b/.test(normalized);
|
|
3810
|
+
return hasProceedSignal && hasPlanReference;
|
|
3785
3811
|
}
|
|
3786
3812
|
function isExecutionDirective(input) {
|
|
3787
|
-
const normalized = input
|
|
3788
|
-
|
|
3813
|
+
const normalized = normalizeDirectiveInput(input);
|
|
3814
|
+
if (!normalized) return false;
|
|
3815
|
+
const directExecution = /* @__PURE__ */ new Set([
|
|
3816
|
+
"execute",
|
|
3817
|
+
"execute atom",
|
|
3818
|
+
"run atom",
|
|
3819
|
+
"run it now",
|
|
3820
|
+
"implement now",
|
|
3821
|
+
"start execution",
|
|
3822
|
+
"go ahead and execute",
|
|
3823
|
+
"execute now",
|
|
3824
|
+
"run now",
|
|
3825
|
+
"start now"
|
|
3826
|
+
]);
|
|
3827
|
+
if (directExecution.has(normalized)) return true;
|
|
3828
|
+
return /\b(execute|run|implement|start)\b/.test(normalized) && /\b(atom|task|plan|it|now)\b/.test(normalized);
|
|
3789
3829
|
}
|
|
3790
3830
|
function isCreateAtomDirective(input) {
|
|
3791
|
-
const normalized = input
|
|
3792
|
-
|
|
3831
|
+
const normalized = normalizeDirectiveInput(input);
|
|
3832
|
+
if (!normalized) return false;
|
|
3833
|
+
const directCreate = /* @__PURE__ */ new Set([
|
|
3834
|
+
"create",
|
|
3835
|
+
"create atom",
|
|
3836
|
+
"save this",
|
|
3837
|
+
"make atom",
|
|
3838
|
+
"save as atom",
|
|
3839
|
+
"turn this into a task",
|
|
3840
|
+
"create task",
|
|
3841
|
+
"save it",
|
|
3842
|
+
"go ahead",
|
|
3843
|
+
"proceed",
|
|
3844
|
+
"yes"
|
|
3845
|
+
]);
|
|
3846
|
+
if (directCreate.has(normalized)) return true;
|
|
3847
|
+
return /\b(create|save|make|turn)\b/.test(normalized) && /\b(atom|task|plan|this|it)\b/.test(normalized);
|
|
3848
|
+
}
|
|
3849
|
+
function normalizeDirectiveInput(input) {
|
|
3850
|
+
return input.trim().toLowerCase().replace(/[^\w\s]/g, " ").replace(/\s+/g, " ").trim();
|
|
3793
3851
|
}
|
|
3794
3852
|
function shouldDoAnalysisBeforeAtom(input) {
|
|
3795
3853
|
const normalized = input.toLowerCase();
|
|
@@ -3816,9 +3874,9 @@ async function applyApprovedProposal(cwd) {
|
|
|
3816
3874
|
console.log(chalk5.dim('\nReply "execute atom" when you want implementation to start, or tell me what to change.'));
|
|
3817
3875
|
}
|
|
3818
3876
|
async function provideAnalysisFirstPlan(cwd, request) {
|
|
3819
|
-
console.log(chalk5.dim("\n>
|
|
3877
|
+
console.log(chalk5.dim("\n> I analyzed your request and generated a recommendation + sample draft first.\n"));
|
|
3820
3878
|
const markdownFiles = collectMarkdownFiles(cwd);
|
|
3821
|
-
const dayOneCandidates = markdownFiles.filter((file) =>
|
|
3879
|
+
const dayOneCandidates = markdownFiles.filter((file) => isDayOnePath(file));
|
|
3822
3880
|
const capsuleCandidates = markdownFiles.filter((file) => /capsule/i.test(file));
|
|
3823
3881
|
const primaryCandidates = dayOneCandidates.length > 0 ? dayOneCandidates : capsuleCandidates;
|
|
3824
3882
|
const reviewedFiles = primaryCandidates.slice(0, 8);
|
|
@@ -3851,9 +3909,15 @@ async function provideAnalysisFirstPlan(cwd, request) {
|
|
|
3851
3909
|
console.log(chalk5.dim(` 2. Define capsule boundaries and titles (${capsuleCount} capsule${capsuleCount > 1 ? "s" : ""}).`));
|
|
3852
3910
|
console.log(chalk5.dim(" 3. Draft capsule markdown(s) with consistent template and learning objective per capsule."));
|
|
3853
3911
|
console.log(chalk5.dim(" 4. Add index/manifest links and quick validation checks for user flow."));
|
|
3912
|
+
const sampleDraft = buildSampleCapsuleDraft(cwd, reviewedFiles, capsuleCount);
|
|
3913
|
+
if (sampleDraft) {
|
|
3914
|
+
console.log();
|
|
3915
|
+
console.log(chalk5.bold("Sample output for day 1 (draft):"));
|
|
3916
|
+
console.log(sampleDraft);
|
|
3917
|
+
}
|
|
3854
3918
|
pendingAnalysisToAtomRequest = request;
|
|
3855
3919
|
console.log();
|
|
3856
|
-
console.log(chalk5.dim('Reply "
|
|
3920
|
+
console.log(chalk5.dim('Reply with "yes", "go ahead", or "create atom" when you want me to implement this in governed mode.'));
|
|
3857
3921
|
}
|
|
3858
3922
|
function collectMarkdownFiles(cwd) {
|
|
3859
3923
|
const results = [];
|
|
@@ -3897,6 +3961,51 @@ function computeContentStats(cwd, files) {
|
|
|
3897
3961
|
}
|
|
3898
3962
|
return { totalWords, totalHeadings };
|
|
3899
3963
|
}
|
|
3964
|
+
function isDayOnePath(path2) {
|
|
3965
|
+
const normalized = path2.toLowerCase();
|
|
3966
|
+
return /\b(day[-_ ]?0*1|lesson[-_ ]?0*1|email[-_ ]?day[-_ ]?0*1)\b/.test(normalized) && !/\b(day[-_ ]?(?:1[0-9]|[2-9])|lesson[-_ ]?(?:1[0-9]|[2-9]))\b/.test(normalized);
|
|
3967
|
+
}
|
|
3968
|
+
function buildSampleCapsuleDraft(cwd, files, capsuleCount) {
|
|
3969
|
+
if (files.length === 0) return null;
|
|
3970
|
+
const primary = files[0];
|
|
3971
|
+
if (!primary) return null;
|
|
3972
|
+
let content = "";
|
|
3973
|
+
try {
|
|
3974
|
+
content = readFileSync3(join6(cwd, primary), "utf-8");
|
|
3975
|
+
} catch {
|
|
3976
|
+
return null;
|
|
3977
|
+
}
|
|
3978
|
+
const lines = content.split("\n").map((line) => line.trim());
|
|
3979
|
+
const heading = lines.find((line) => line.startsWith("#"))?.replace(/^#+\s*/, "") || "Day 1 Lesson";
|
|
3980
|
+
const paragraphs = content.split("\n\n").map((p) => p.replace(/\s+/g, " ").trim()).filter((p) => p.length > 40 && !p.startsWith("#") && !p.startsWith("- ") && !p.startsWith("* "));
|
|
3981
|
+
const objective = paragraphs[0] ?? "Introduce the day-1 core idea with a clear, practical framing.";
|
|
3982
|
+
const concept = paragraphs[1] ?? "Explain the key concept in plain language with one relatable example.";
|
|
3983
|
+
const practice = paragraphs[2] ?? "Give one guided prompt so the learner can apply the idea immediately.";
|
|
3984
|
+
if (capsuleCount <= 1) {
|
|
3985
|
+
return [
|
|
3986
|
+
chalk5.dim(" ---"),
|
|
3987
|
+
chalk5.dim(` title: "${heading} - Core Capsule"`),
|
|
3988
|
+
chalk5.dim(' type: "lesson_capsule"'),
|
|
3989
|
+
chalk5.dim(" day: 1"),
|
|
3990
|
+
chalk5.dim(" ---"),
|
|
3991
|
+
chalk5.dim(" ## Objective"),
|
|
3992
|
+
chalk5.dim(` ${objective}`),
|
|
3993
|
+
chalk5.dim(" ## Core Concept"),
|
|
3994
|
+
chalk5.dim(` ${concept}`),
|
|
3995
|
+
chalk5.dim(" ## Practice"),
|
|
3996
|
+
chalk5.dim(` ${practice}`)
|
|
3997
|
+
].join("\n");
|
|
3998
|
+
}
|
|
3999
|
+
return [
|
|
4000
|
+
chalk5.dim(" Capsule 1: Foundation"),
|
|
4001
|
+
chalk5.dim(` - Objective: ${objective}`),
|
|
4002
|
+
chalk5.dim(` - Core Concept: ${concept}`),
|
|
4003
|
+
chalk5.dim(""),
|
|
4004
|
+
chalk5.dim(" Capsule 2: Application"),
|
|
4005
|
+
chalk5.dim(` - Guided Practice: ${practice}`),
|
|
4006
|
+
chalk5.dim(" - Reflection Prompt: What changed in your understanding after this exercise?")
|
|
4007
|
+
].join("\n");
|
|
4008
|
+
}
|
|
3900
4009
|
async function continueWithCurrentTask(cwd) {
|
|
3901
4010
|
const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-RHDFDSZE.js");
|
|
3902
4011
|
const atoms = await listLocalAtoms2();
|
|
@@ -4031,6 +4140,10 @@ function containsActionIntent(input) {
|
|
|
4031
4140
|
async function handlePostExploreAction(cwd, request, options = {}) {
|
|
4032
4141
|
const sourceInput = options.originalInput?.trim() || request;
|
|
4033
4142
|
if (wantsProposalBeforeExecution(sourceInput)) {
|
|
4143
|
+
if (shouldDoAnalysisBeforeAtom(sourceInput)) {
|
|
4144
|
+
await provideAnalysisFirstPlan(cwd, sourceInput);
|
|
4145
|
+
return;
|
|
4146
|
+
}
|
|
4034
4147
|
await showProposalForApproval(sourceInput);
|
|
4035
4148
|
return;
|
|
4036
4149
|
}
|