archondev 2.14.0 → 2.17.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.
- package/README.md +2 -0
- package/dist/{auth-2E4VORGY.js → auth-KUFS3PBS.js} +3 -3
- package/dist/{bug-KUMC6HSR.js → bug-BJH4X5LI.js} +3 -2
- package/dist/{chunk-3JURZUY7.js → chunk-2QIXLBAC.js} +1 -1
- package/dist/{chunk-P666JE3G.js → chunk-54ATBLYE.js} +1 -1
- package/dist/{chunk-NLW75APJ.js → chunk-DUJOT5B6.js} +7 -7
- package/dist/{chunk-DQE6E436.js → chunk-E7ZTIAQM.js} +63 -28
- package/dist/{chunk-JWY56A3X.js → chunk-FA2GAZ7L.js} +8 -12
- package/dist/{chunk-P4KDRIFM.js → chunk-HTJOCKVV.js} +4 -4
- package/dist/{chunk-CJ3CFP52.js → chunk-LHCXE6UL.js} +71 -21
- package/dist/{chunk-35AOCHTE.js → chunk-LPSS2U5V.js} +7 -3
- package/dist/{chunk-SVU7MLG6.js → chunk-SUGIWSCB.js} +24 -5
- package/dist/{chunk-KMVMRFQ5.js → chunk-TRLP7RMZ.js} +11 -1
- package/dist/{chunk-7NSVJFIZ.js → chunk-WZIRUPMP.js} +1 -1
- package/dist/{config-BBQW726O.js → config-USLUSE4N.js} +2 -1
- package/dist/{execute-MAFSY5FY.js → execute-73QW4ZEZ.js} +3 -3
- package/dist/index.js +356 -104
- package/dist/{init-6EXMDCWC.js → init-PSMJLDEZ.js} +1 -1
- package/dist/{interviewer-SULVHQW6.js → interviewer-Q6PFSAGT.js} +2 -1
- package/dist/{keys-5Y7KQAHI.js → keys-VLK3EWSN.js} +3 -2
- package/dist/{list-C224HUQ6.js → list-MMKB5TGX.js} +3 -3
- package/dist/{parallel-4NN4ONOH.js → parallel-WHFKRBPR.js} +3 -3
- package/dist/{plan-7DPVPUNK.js → plan-X77BUKNE.js} +4 -2
- package/dist/{preferences-32J3GUTY.js → preferences-TWEK2RWY.js} +4 -4
- package/dist/{tier-selection-3N4BZYWA.js → tier-selection-Z2RFHZUX.js} +3 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -99,6 +99,8 @@ Copy governance files into any project. Works with your existing AI tools: **Cur
|
|
|
99
99
|
| `archon cleanup run` | Execute cleanup tasks |
|
|
100
100
|
| `archon cleanup auto [enable\|disable]` | Enable/disable auto cleanup on start |
|
|
101
101
|
|
|
102
|
+
**Tip:** Use `archon plan --edit` to adjust title and acceptance criteria before planning.
|
|
103
|
+
|
|
102
104
|
## Pricing
|
|
103
105
|
|
|
104
106
|
| Tier | Cost | What You Get |
|
|
@@ -2,10 +2,10 @@ import {
|
|
|
2
2
|
login,
|
|
3
3
|
logout,
|
|
4
4
|
status
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-FA2GAZ7L.js";
|
|
6
|
+
import "./chunk-DUJOT5B6.js";
|
|
7
|
+
import "./chunk-SUGIWSCB.js";
|
|
6
8
|
import "./chunk-M4LGRTLC.js";
|
|
7
|
-
import "./chunk-NLW75APJ.js";
|
|
8
|
-
import "./chunk-SVU7MLG6.js";
|
|
9
9
|
import "./chunk-QGM4M3NI.js";
|
|
10
10
|
export {
|
|
11
11
|
login,
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
bugReport
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-2QIXLBAC.js";
|
|
4
4
|
import "./chunk-ER4ADSWH.js";
|
|
5
5
|
import "./chunk-NIKN37AY.js";
|
|
6
6
|
import "./chunk-LXXTCZ2Q.js";
|
|
7
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-SUGIWSCB.js";
|
|
8
|
+
import "./chunk-M4LGRTLC.js";
|
|
8
9
|
import "./chunk-QGM4M3NI.js";
|
|
9
10
|
export {
|
|
10
11
|
bugReport
|
|
@@ -13,7 +13,7 @@ function isInitialized(cwd) {
|
|
|
13
13
|
if (existsSync(archMdPath)) {
|
|
14
14
|
try {
|
|
15
15
|
const content = readFileSync(archMdPath, "utf-8");
|
|
16
|
-
return content.startsWith("---") && content.includes("version:") && content.includes("
|
|
16
|
+
return content.startsWith("---") && content.includes("version:") && (content.includes("systemGoals:") || content.includes("components:") || content.includes("profile:"));
|
|
17
17
|
} catch {
|
|
18
18
|
return false;
|
|
19
19
|
}
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
getApiUrl,
|
|
3
3
|
loadConfig,
|
|
4
4
|
saveConfig
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-SUGIWSCB.js";
|
|
6
6
|
|
|
7
7
|
// src/cli/tier-selection.ts
|
|
8
8
|
import chalk from "chalk";
|
|
@@ -43,9 +43,9 @@ async function offerReauthentication(reason) {
|
|
|
43
43
|
return false;
|
|
44
44
|
}
|
|
45
45
|
console.log();
|
|
46
|
-
const { login } = await import("./auth-
|
|
46
|
+
const { login } = await import("./auth-KUFS3PBS.js");
|
|
47
47
|
await login({ skipTierSelection: true });
|
|
48
|
-
const { loadConfig: reload } = await import("./config-
|
|
48
|
+
const { loadConfig: reload } = await import("./config-USLUSE4N.js");
|
|
49
49
|
const config = await reload();
|
|
50
50
|
return !!(config && config.accessToken);
|
|
51
51
|
}
|
|
@@ -207,7 +207,7 @@ async function promptForApiKey() {
|
|
|
207
207
|
return;
|
|
208
208
|
}
|
|
209
209
|
if (provider) {
|
|
210
|
-
const { addKey } = await import("./keys-
|
|
210
|
+
const { addKey } = await import("./keys-VLK3EWSN.js");
|
|
211
211
|
await addKey(provider, {});
|
|
212
212
|
console.log();
|
|
213
213
|
const addAnother = await promptYesNo("Would you like to add another API key?", false);
|
|
@@ -219,7 +219,7 @@ async function promptForApiKey() {
|
|
|
219
219
|
async function createCheckoutSession(amountCents) {
|
|
220
220
|
const spinner = ora("Preparing checkout...").start();
|
|
221
221
|
try {
|
|
222
|
-
const { ensureValidSession, loadConfig: loadConfig2 } = await import("./config-
|
|
222
|
+
const { ensureValidSession, loadConfig: loadConfig2 } = await import("./config-USLUSE4N.js");
|
|
223
223
|
let config = await ensureValidSession();
|
|
224
224
|
if (!config || !config.accessToken || !config.userId) {
|
|
225
225
|
spinner.stop();
|
|
@@ -367,7 +367,7 @@ Switching to ${selectedName}...`));
|
|
|
367
367
|
var showTierSwitchMenu = showUpgradeMenu;
|
|
368
368
|
async function updateUserTier(tier, _alreadyRetried = false) {
|
|
369
369
|
try {
|
|
370
|
-
const { ensureValidSession, loadConfig: reload } = await import("./config-
|
|
370
|
+
const { ensureValidSession, loadConfig: reload } = await import("./config-USLUSE4N.js");
|
|
371
371
|
let config = await ensureValidSession();
|
|
372
372
|
if (!config || !config.accessToken) {
|
|
373
373
|
if (_alreadyRetried) {
|
|
@@ -455,7 +455,7 @@ function promptYesNo(question, defaultValue) {
|
|
|
455
455
|
}
|
|
456
456
|
async function showKeyManagementMenu() {
|
|
457
457
|
const { keyManager } = await import("./keys-SXJ6MKPY.js");
|
|
458
|
-
const { listKeys, addKey, removeKey } = await import("./keys-
|
|
458
|
+
const { listKeys, addKey, removeKey } = await import("./keys-VLK3EWSN.js");
|
|
459
459
|
console.log();
|
|
460
460
|
console.log(chalk.bold("API Key Management"));
|
|
461
461
|
console.log(chalk.dim("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"));
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
UsageRecorder,
|
|
3
|
-
loadAtom
|
|
4
|
-
|
|
3
|
+
loadAtom,
|
|
4
|
+
loadRoleOverrides
|
|
5
|
+
} from "./chunk-LHCXE6UL.js";
|
|
5
6
|
import {
|
|
6
7
|
ArchitectureParser
|
|
7
8
|
} from "./chunk-5EVHUDQX.js";
|
|
@@ -12,14 +13,15 @@ import {
|
|
|
12
13
|
AnthropicClient,
|
|
13
14
|
getDefaultModel
|
|
14
15
|
} from "./chunk-NIKN37AY.js";
|
|
16
|
+
import {
|
|
17
|
+
createAuthedSupabaseClient,
|
|
18
|
+
getAuthToken,
|
|
19
|
+
loadConfig
|
|
20
|
+
} from "./chunk-SUGIWSCB.js";
|
|
15
21
|
import {
|
|
16
22
|
SUPABASE_ANON_KEY,
|
|
17
23
|
SUPABASE_URL
|
|
18
24
|
} from "./chunk-M4LGRTLC.js";
|
|
19
|
-
import {
|
|
20
|
-
getAuthToken,
|
|
21
|
-
loadConfig
|
|
22
|
-
} from "./chunk-SVU7MLG6.js";
|
|
23
25
|
import {
|
|
24
26
|
__commonJS,
|
|
25
27
|
__require,
|
|
@@ -2854,15 +2856,13 @@ import chalk3 from "chalk";
|
|
|
2854
2856
|
import { existsSync as existsSync8 } from "fs";
|
|
2855
2857
|
import { readFile as readFile7, writeFile as writeFile4 } from "fs/promises";
|
|
2856
2858
|
import { join as join3 } from "path";
|
|
2857
|
-
import {
|
|
2859
|
+
import { spawnSync as spawnSync2 } from "child_process";
|
|
2858
2860
|
import { createInterface } from "readline";
|
|
2859
|
-
import { createClient as createClient2 } from "@supabase/supabase-js";
|
|
2860
2861
|
|
|
2861
2862
|
// src/cli/cloud.ts
|
|
2862
2863
|
import chalk from "chalk";
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
return createClient(SUPABASE_URL, SUPABASE_ANON_KEY);
|
|
2864
|
+
function getClient(accessToken) {
|
|
2865
|
+
return createAuthedSupabaseClient(SUPABASE_URL, SUPABASE_ANON_KEY, accessToken);
|
|
2866
2866
|
}
|
|
2867
2867
|
async function cloudStatus() {
|
|
2868
2868
|
const config = await loadConfig();
|
|
@@ -2871,7 +2871,7 @@ async function cloudStatus() {
|
|
|
2871
2871
|
console.error(chalk.red('Not authenticated. Run "archon login" first.'));
|
|
2872
2872
|
process.exit(1);
|
|
2873
2873
|
}
|
|
2874
|
-
const client = getClient();
|
|
2874
|
+
const client = getClient(authToken);
|
|
2875
2875
|
const { data, error } = await client.from("cloud_executions").select("*").order("created_at", { ascending: false }).limit(20);
|
|
2876
2876
|
if (error) {
|
|
2877
2877
|
console.error(chalk.red("Failed to fetch cloud executions:"), error.message);
|
|
@@ -2907,7 +2907,7 @@ async function cloudCancel(executionId) {
|
|
|
2907
2907
|
console.error(chalk.red('Not authenticated. Run "archon login" first.'));
|
|
2908
2908
|
process.exit(1);
|
|
2909
2909
|
}
|
|
2910
|
-
const client = getClient();
|
|
2910
|
+
const client = getClient(authToken);
|
|
2911
2911
|
const { data: existing, error: fetchError } = await client.from("cloud_executions").select("id, status").eq("id", executionId).single();
|
|
2912
2912
|
if (fetchError || !existing) {
|
|
2913
2913
|
console.error(chalk.red(`Execution ${executionId} not found.`));
|
|
@@ -2931,7 +2931,7 @@ async function cloudLogs(executionId) {
|
|
|
2931
2931
|
console.error(chalk.red('Not authenticated. Run "archon login" first.'));
|
|
2932
2932
|
process.exit(1);
|
|
2933
2933
|
}
|
|
2934
|
-
const client = getClient();
|
|
2934
|
+
const client = getClient(authToken);
|
|
2935
2935
|
const { data, error } = await client.from("cloud_executions").select("id, atom_id, status, logs").eq("id", executionId).single();
|
|
2936
2936
|
if (error || !data) {
|
|
2937
2937
|
console.error(chalk.red(`Execution ${executionId} not found.`));
|
|
@@ -2960,7 +2960,7 @@ async function queueCloudExecution(atomId, projectName, options) {
|
|
|
2960
2960
|
if (!authToken) {
|
|
2961
2961
|
throw new Error('Not authenticated. Run "archon login" first.');
|
|
2962
2962
|
}
|
|
2963
|
-
const client = getClient();
|
|
2963
|
+
const client = getClient(authToken);
|
|
2964
2964
|
const insertData = {
|
|
2965
2965
|
atom_id: atomId,
|
|
2966
2966
|
project_name: projectName,
|
|
@@ -4681,6 +4681,33 @@ var TrackedExecutorAgent = class {
|
|
|
4681
4681
|
}
|
|
4682
4682
|
};
|
|
4683
4683
|
|
|
4684
|
+
// src/core/git/rollback.ts
|
|
4685
|
+
import { spawnSync } from "child_process";
|
|
4686
|
+
function rollbackFiles(cwd, files) {
|
|
4687
|
+
if (files.length === 0) return;
|
|
4688
|
+
const tracked = [];
|
|
4689
|
+
const untracked = [];
|
|
4690
|
+
for (const file of files) {
|
|
4691
|
+
const result = spawnSync("git", ["ls-files", "--error-unmatch", file], { cwd, stdio: "pipe" });
|
|
4692
|
+
if (result.status === 0) {
|
|
4693
|
+
tracked.push(file);
|
|
4694
|
+
} else {
|
|
4695
|
+
untracked.push(file);
|
|
4696
|
+
}
|
|
4697
|
+
}
|
|
4698
|
+
if (tracked.length > 0) {
|
|
4699
|
+
const checkout = spawnSync("git", ["checkout", "--", ...tracked], { cwd, stdio: "pipe" });
|
|
4700
|
+
if (checkout.status !== 0) {
|
|
4701
|
+
throw new Error(checkout.stderr?.toString() || "git checkout failed");
|
|
4702
|
+
}
|
|
4703
|
+
}
|
|
4704
|
+
const cleanTargets = untracked.length > 0 ? untracked : files;
|
|
4705
|
+
const clean = spawnSync("git", ["clean", "-f", "--", ...cleanTargets], { cwd, stdio: "pipe" });
|
|
4706
|
+
if (clean.status !== 0) {
|
|
4707
|
+
throw new Error(clean.stderr?.toString() || "git clean failed");
|
|
4708
|
+
}
|
|
4709
|
+
}
|
|
4710
|
+
|
|
4684
4711
|
// src/core/environments/types.ts
|
|
4685
4712
|
var DEFAULT_ENVIRONMENTS = {
|
|
4686
4713
|
development: {
|
|
@@ -4895,9 +4922,9 @@ function createPrompt() {
|
|
|
4895
4922
|
}
|
|
4896
4923
|
async function execute(atomId, options) {
|
|
4897
4924
|
if (options.parallel && options.parallel.length > 0) {
|
|
4898
|
-
const { parallelExecute } = await import("./parallel-
|
|
4925
|
+
const { parallelExecute } = await import("./parallel-WHFKRBPR.js");
|
|
4899
4926
|
const allAtomIds = [atomId, ...options.parallel];
|
|
4900
|
-
await parallelExecute(allAtomIds);
|
|
4927
|
+
await parallelExecute(allAtomIds, { skipGates: options.skipGates === true });
|
|
4901
4928
|
return;
|
|
4902
4929
|
}
|
|
4903
4930
|
const prompt = createPrompt();
|
|
@@ -5042,14 +5069,16 @@ ${conflictReport.blockerCount} blocking conflict(s) found.`));
|
|
|
5042
5069
|
console.log(chalk3.blue("\n\u{1F680} Executing plan..."));
|
|
5043
5070
|
const config = await loadConfig();
|
|
5044
5071
|
let billingContext;
|
|
5045
|
-
if (config.userId) {
|
|
5046
|
-
const supabase =
|
|
5072
|
+
if (config.userId && config.accessToken) {
|
|
5073
|
+
const supabase = createAuthedSupabaseClient(SUPABASE_URL, SUPABASE_ANON_KEY, config.accessToken);
|
|
5047
5074
|
billingContext = {
|
|
5048
5075
|
userId: config.userId,
|
|
5049
5076
|
supabase
|
|
5050
5077
|
};
|
|
5051
5078
|
}
|
|
5052
|
-
const
|
|
5079
|
+
const roleOverrides = await loadRoleOverrides(cwd);
|
|
5080
|
+
const executorConfig = roleOverrides?.executor?.model ? { model: roleOverrides.executor.model } : void 0;
|
|
5081
|
+
const executor = billingContext ? new TrackedExecutorAgent({ billing: billingContext, clientConfig: executorConfig }) : new ExecutorAgent(executorConfig);
|
|
5053
5082
|
if (billingContext && executor instanceof TrackedExecutorAgent) {
|
|
5054
5083
|
const balanceCheck = await executor.checkBalance();
|
|
5055
5084
|
if (!balanceCheck.sufficient && balanceCheck.tier === "CREDITS") {
|
|
@@ -5106,10 +5135,11 @@ Running quality gates for ${targetEnvName}...`));
|
|
|
5106
5135
|
console.log(chalk3.red("\n\u274C Quality gates failed"));
|
|
5107
5136
|
console.log(chalk3.yellow("Rolling back changes..."));
|
|
5108
5137
|
try {
|
|
5109
|
-
|
|
5110
|
-
console.log(chalk3.yellow("Changes rolled back."));
|
|
5111
|
-
} catch {
|
|
5138
|
+
rollbackFiles(cwd, filesChanged);
|
|
5139
|
+
console.log(chalk3.yellow("Changes rolled back (scoped to atom files)."));
|
|
5140
|
+
} catch (error) {
|
|
5112
5141
|
console.log(chalk3.red("Failed to rollback. Please manually revert changes."));
|
|
5142
|
+
console.log(chalk3.dim(error instanceof Error ? error.message : "Unknown rollback error"));
|
|
5113
5143
|
}
|
|
5114
5144
|
transitionAtom(atom, "FAILED");
|
|
5115
5145
|
atom.errorMessage = `Quality gate failed: ${gateResult.failedAt}`;
|
|
@@ -5132,8 +5162,14 @@ Running quality gates for ${targetEnvName}...`));
|
|
|
5132
5162
|
console.log(chalk3.dim("\nCommitting changes..."));
|
|
5133
5163
|
try {
|
|
5134
5164
|
const commitMessage = `feat: [${atom.externalId}] - ${atom.title}`;
|
|
5135
|
-
|
|
5136
|
-
|
|
5165
|
+
const addResult = spawnSync2("git", ["add", "-A"], { cwd, stdio: "pipe" });
|
|
5166
|
+
if (addResult.status !== 0) {
|
|
5167
|
+
throw new Error(addResult.stderr?.toString() || "git add failed");
|
|
5168
|
+
}
|
|
5169
|
+
const commitResult = spawnSync2("git", ["commit", "-m", commitMessage], { cwd, stdio: "pipe" });
|
|
5170
|
+
if (commitResult.status !== 0) {
|
|
5171
|
+
throw new Error(commitResult.stderr?.toString() || "git commit failed");
|
|
5172
|
+
}
|
|
5137
5173
|
console.log(chalk3.green(`\u2713 Committed: ${commitMessage}`));
|
|
5138
5174
|
} catch (error) {
|
|
5139
5175
|
console.log(chalk3.yellow("No changes to commit or git commit failed."));
|
|
@@ -5223,13 +5259,12 @@ async function watchCloudExecution(executionId) {
|
|
|
5223
5259
|
const pollInterval = 5e3;
|
|
5224
5260
|
let lastLogCount = 0;
|
|
5225
5261
|
const poll = async () => {
|
|
5226
|
-
const { loadConfig: loadConfig2, getAuthToken: getAuthToken2 } = await import("./config-
|
|
5227
|
-
const { createClient: createClient3 } = await import("@supabase/supabase-js");
|
|
5262
|
+
const { loadConfig: loadConfig2, getAuthToken: getAuthToken2 } = await import("./config-USLUSE4N.js");
|
|
5228
5263
|
const { SUPABASE_URL: SUPABASE_URL2, SUPABASE_ANON_KEY: SUPABASE_ANON_KEY2 } = await import("./constants-AHP5F7HW.js");
|
|
5229
5264
|
const config = await loadConfig2();
|
|
5230
5265
|
const authToken = getAuthToken2(config);
|
|
5231
5266
|
if (!authToken) return true;
|
|
5232
|
-
const client =
|
|
5267
|
+
const client = createAuthedSupabaseClient(SUPABASE_URL2, SUPABASE_ANON_KEY2, authToken);
|
|
5233
5268
|
const { data } = await client.from("cloud_executions").select("status, logs, error_message, result_branch, result_pr_url").eq("id", executionId).single();
|
|
5234
5269
|
if (!data) return true;
|
|
5235
5270
|
const logs = data.logs ?? [];
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
SUPABASE_ANON_KEY,
|
|
3
|
-
SUPABASE_URL
|
|
4
|
-
} from "./chunk-M4LGRTLC.js";
|
|
5
1
|
import {
|
|
6
2
|
handleTierSetup,
|
|
7
3
|
promptTierSelection,
|
|
8
4
|
updateUserTier
|
|
9
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-DUJOT5B6.js";
|
|
10
6
|
import {
|
|
11
7
|
clearConfig,
|
|
8
|
+
createPkceSupabaseClient,
|
|
12
9
|
loadConfig,
|
|
13
10
|
saveConfig
|
|
14
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-SUGIWSCB.js";
|
|
12
|
+
import {
|
|
13
|
+
SUPABASE_ANON_KEY,
|
|
14
|
+
SUPABASE_URL
|
|
15
|
+
} from "./chunk-M4LGRTLC.js";
|
|
15
16
|
|
|
16
17
|
// src/cli/auth.ts
|
|
17
|
-
import { createClient } from "@supabase/supabase-js";
|
|
18
18
|
import { createServer } from "http";
|
|
19
19
|
import { URL } from "url";
|
|
20
20
|
import readline from "readline";
|
|
@@ -24,11 +24,7 @@ import ora from "ora";
|
|
|
24
24
|
var CALLBACK_PORT = 54321;
|
|
25
25
|
var CALLBACK_URL = `http://localhost:${CALLBACK_PORT}/callback`;
|
|
26
26
|
function getAuthClient() {
|
|
27
|
-
return
|
|
28
|
-
auth: {
|
|
29
|
-
flowType: "pkce"
|
|
30
|
-
}
|
|
31
|
-
});
|
|
27
|
+
return createPkceSupabaseClient(SUPABASE_URL, SUPABASE_ANON_KEY);
|
|
32
28
|
}
|
|
33
29
|
async function login(providerOrOptions = "github") {
|
|
34
30
|
const options = typeof providerOrOptions === "string" ? { provider: providerOrOptions } : providerOrOptions;
|
|
@@ -14,12 +14,12 @@ import {
|
|
|
14
14
|
} from "./chunk-RDG5BUED.js";
|
|
15
15
|
import {
|
|
16
16
|
login
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-FA2GAZ7L.js";
|
|
18
18
|
import {
|
|
19
19
|
getApiUrl,
|
|
20
20
|
getAuthToken,
|
|
21
21
|
loadConfig
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-SUGIWSCB.js";
|
|
23
23
|
|
|
24
24
|
// src/cli/preferences.ts
|
|
25
25
|
import chalk from "chalk";
|
|
@@ -1071,7 +1071,7 @@ async function manageApiKeys() {
|
|
|
1071
1071
|
if (removeIndex >= 0 && removeIndex < providers.length) {
|
|
1072
1072
|
const providerToRemove = providers[removeIndex];
|
|
1073
1073
|
if (providerToRemove) {
|
|
1074
|
-
const { removeKey } = await import("./keys-
|
|
1074
|
+
const { removeKey } = await import("./keys-VLK3EWSN.js");
|
|
1075
1075
|
await removeKey(providerToRemove);
|
|
1076
1076
|
}
|
|
1077
1077
|
}
|
|
@@ -1079,7 +1079,7 @@ async function manageApiKeys() {
|
|
|
1079
1079
|
}
|
|
1080
1080
|
const provider = providerMap[choice];
|
|
1081
1081
|
if (provider) {
|
|
1082
|
-
const { addKey } = await import("./keys-
|
|
1082
|
+
const { addKey } = await import("./keys-VLK3EWSN.js");
|
|
1083
1083
|
await addKey(provider);
|
|
1084
1084
|
}
|
|
1085
1085
|
}
|
|
@@ -13,22 +13,22 @@ import {
|
|
|
13
13
|
import {
|
|
14
14
|
KeyManager
|
|
15
15
|
} from "./chunk-RDG5BUED.js";
|
|
16
|
+
import {
|
|
17
|
+
createAuthedSupabaseClient,
|
|
18
|
+
isAuthenticated,
|
|
19
|
+
loadConfig
|
|
20
|
+
} from "./chunk-SUGIWSCB.js";
|
|
16
21
|
import {
|
|
17
22
|
SUPABASE_ANON_KEY,
|
|
18
23
|
SUPABASE_URL
|
|
19
24
|
} from "./chunk-M4LGRTLC.js";
|
|
20
|
-
import {
|
|
21
|
-
isAuthenticated,
|
|
22
|
-
loadConfig
|
|
23
|
-
} from "./chunk-SVU7MLG6.js";
|
|
24
25
|
|
|
25
26
|
// src/cli/plan.ts
|
|
26
27
|
import chalk from "chalk";
|
|
27
|
-
import { existsSync } from "fs";
|
|
28
|
-
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
29
|
-
import { join } from "path";
|
|
28
|
+
import { existsSync as existsSync2 } from "fs";
|
|
29
|
+
import { readFile as readFile2, writeFile, mkdir } from "fs/promises";
|
|
30
|
+
import { join as join2 } from "path";
|
|
30
31
|
import { createInterface } from "readline";
|
|
31
|
-
import { createClient } from "@supabase/supabase-js";
|
|
32
32
|
|
|
33
33
|
// src/agents/sentinel.ts
|
|
34
34
|
var SYSTEM_PROMPT = `You are the Sentinel, a paranoid and skeptical code reviewer responsible for finding issues in implementation plans.
|
|
@@ -732,6 +732,31 @@ var TrackedAdversarialPlanner = class {
|
|
|
732
732
|
}
|
|
733
733
|
};
|
|
734
734
|
|
|
735
|
+
// src/core/config/roles.ts
|
|
736
|
+
import { existsSync } from "fs";
|
|
737
|
+
import { readFile } from "fs/promises";
|
|
738
|
+
import { join } from "path";
|
|
739
|
+
import yaml from "yaml";
|
|
740
|
+
async function loadRoleOverrides(cwd = process.cwd()) {
|
|
741
|
+
const candidates = [
|
|
742
|
+
join(cwd, ".archon", "config.yaml"),
|
|
743
|
+
join(cwd, "archon.config.yaml")
|
|
744
|
+
];
|
|
745
|
+
for (const path of candidates) {
|
|
746
|
+
if (!existsSync(path)) continue;
|
|
747
|
+
try {
|
|
748
|
+
const content = await readFile(path, "utf-8");
|
|
749
|
+
const parsed = yaml.parse(content);
|
|
750
|
+
if (parsed?.roles) {
|
|
751
|
+
return parsed.roles;
|
|
752
|
+
}
|
|
753
|
+
} catch {
|
|
754
|
+
continue;
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
return null;
|
|
758
|
+
}
|
|
759
|
+
|
|
735
760
|
// src/cli/plan.ts
|
|
736
761
|
var ATOMS_DIR = ".archon/atoms";
|
|
737
762
|
function createPrompt() {
|
|
@@ -753,8 +778,8 @@ async function plan(description, options) {
|
|
|
753
778
|
console.log(chalk.yellow('Not authenticated. Run "archon login" first.'));
|
|
754
779
|
console.log(chalk.dim("For local development, you can continue without authentication."));
|
|
755
780
|
}
|
|
756
|
-
const archPath =
|
|
757
|
-
if (!
|
|
781
|
+
const archPath = join2(process.cwd(), "ARCHITECTURE.md");
|
|
782
|
+
if (!existsSync2(archPath)) {
|
|
758
783
|
console.error(chalk.red('ARCHITECTURE.md not found. Run "archon init" first.'));
|
|
759
784
|
process.exit(1);
|
|
760
785
|
}
|
|
@@ -779,6 +804,26 @@ async function plan(description, options) {
|
|
|
779
804
|
}
|
|
780
805
|
process.exit(1);
|
|
781
806
|
}
|
|
807
|
+
if (options.edit) {
|
|
808
|
+
console.log(chalk.dim("\nEdit mode: update title and acceptance criteria (press Enter to keep current)."));
|
|
809
|
+
const newTitle = await prompt.ask(`Title [${atom.title}]: `);
|
|
810
|
+
if (newTitle.trim()) {
|
|
811
|
+
atom.title = newTitle.trim();
|
|
812
|
+
}
|
|
813
|
+
const acCurrent = atom.acceptanceCriteria.join(", ");
|
|
814
|
+
const newAc = await prompt.ask(`Acceptance criteria (comma-separated) [${acCurrent}]: `);
|
|
815
|
+
if (newAc.trim()) {
|
|
816
|
+
atom.acceptanceCriteria = newAc.split(",").map((ac) => ac.trim()).filter(Boolean);
|
|
817
|
+
}
|
|
818
|
+
const revalidation = validateAtom(atom);
|
|
819
|
+
if (!revalidation.valid) {
|
|
820
|
+
console.error(chalk.red("Invalid atom after edits:"));
|
|
821
|
+
for (const error of revalidation.errors) {
|
|
822
|
+
console.error(chalk.red(` - ${error.field}: ${error.message}`));
|
|
823
|
+
}
|
|
824
|
+
process.exit(1);
|
|
825
|
+
}
|
|
826
|
+
}
|
|
782
827
|
console.log(chalk.blue(`
|
|
783
828
|
Atom created: ${atom.externalId}`));
|
|
784
829
|
console.log(chalk.dim(`Title: ${atom.title}`));
|
|
@@ -804,14 +849,17 @@ Atom saved: ${atom.externalId}`));
|
|
|
804
849
|
console.log(chalk.dim("Architect will generate a plan, Sentinel will validate it.\n"));
|
|
805
850
|
const config = await loadConfig();
|
|
806
851
|
let billingContext;
|
|
807
|
-
if (config.userId) {
|
|
808
|
-
const supabase =
|
|
852
|
+
if (config.userId && config.accessToken) {
|
|
853
|
+
const supabase = createAuthedSupabaseClient(SUPABASE_URL, SUPABASE_ANON_KEY, config.accessToken);
|
|
809
854
|
billingContext = {
|
|
810
855
|
userId: config.userId,
|
|
811
856
|
supabase
|
|
812
857
|
};
|
|
813
858
|
}
|
|
814
|
-
const
|
|
859
|
+
const roleOverrides = await loadRoleOverrides(process.cwd());
|
|
860
|
+
const architectConfig = roleOverrides?.architect?.model ? { model: roleOverrides.architect.model } : void 0;
|
|
861
|
+
const sentinelConfig = roleOverrides?.sentinel?.model ? { model: roleOverrides.sentinel.model } : void 0;
|
|
862
|
+
const planner = billingContext ? new TrackedAdversarialPlanner({ apiKey, billing: billingContext, architectConfig, sentinelConfig }) : new AdversarialPlanner({ apiKey, architectConfig, sentinelConfig });
|
|
815
863
|
if (billingContext && planner instanceof TrackedAdversarialPlanner) {
|
|
816
864
|
const balanceCheck = await planner.checkBalance();
|
|
817
865
|
if (!balanceCheck.sufficient && balanceCheck.tier === "CREDITS") {
|
|
@@ -925,24 +973,24 @@ function displayPlan(plan2) {
|
|
|
925
973
|
console.log(chalk.bold("\nComplexity:"), plan2.estimated_complexity);
|
|
926
974
|
}
|
|
927
975
|
async function saveAtom(atom) {
|
|
928
|
-
const atomsDir =
|
|
929
|
-
if (!
|
|
976
|
+
const atomsDir = join2(process.cwd(), ATOMS_DIR);
|
|
977
|
+
if (!existsSync2(atomsDir)) {
|
|
930
978
|
await mkdir(atomsDir, { recursive: true });
|
|
931
979
|
}
|
|
932
|
-
const atomFile =
|
|
980
|
+
const atomFile = join2(atomsDir, `${atom.externalId}.json`);
|
|
933
981
|
await writeFile(atomFile, JSON.stringify(atom, null, 2));
|
|
934
982
|
}
|
|
935
983
|
async function loadAtom(atomId) {
|
|
936
|
-
const atomFile =
|
|
937
|
-
if (!
|
|
984
|
+
const atomFile = join2(process.cwd(), ATOMS_DIR, `${atomId}.json`);
|
|
985
|
+
if (!existsSync2(atomFile)) {
|
|
938
986
|
return null;
|
|
939
987
|
}
|
|
940
|
-
const content = await
|
|
988
|
+
const content = await readFile2(atomFile, "utf-8");
|
|
941
989
|
return JSON.parse(content);
|
|
942
990
|
}
|
|
943
991
|
async function listLocalAtoms() {
|
|
944
|
-
const atomsDir =
|
|
945
|
-
if (!
|
|
992
|
+
const atomsDir = join2(process.cwd(), ATOMS_DIR);
|
|
993
|
+
if (!existsSync2(atomsDir)) {
|
|
946
994
|
return [];
|
|
947
995
|
}
|
|
948
996
|
const { readdir } = await import("fs/promises");
|
|
@@ -961,7 +1009,9 @@ async function listLocalAtoms() {
|
|
|
961
1009
|
|
|
962
1010
|
export {
|
|
963
1011
|
UsageRecorder,
|
|
1012
|
+
loadRoleOverrides,
|
|
964
1013
|
plan,
|
|
1014
|
+
parseAtomDescription,
|
|
965
1015
|
loadAtom,
|
|
966
1016
|
listLocalAtoms
|
|
967
1017
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
listLocalAtoms,
|
|
3
3
|
loadAtom
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-LHCXE6UL.js";
|
|
5
5
|
|
|
6
6
|
// src/cli/parallel.ts
|
|
7
7
|
import chalk from "chalk";
|
|
@@ -359,7 +359,7 @@ async function saveParallelState(cwd, state) {
|
|
|
359
359
|
const statePath = join2(cwd, PARALLEL_STATE_FILE);
|
|
360
360
|
await writeFile(statePath, JSON.stringify(state, null, 2));
|
|
361
361
|
}
|
|
362
|
-
async function parallelExecute(atomIds) {
|
|
362
|
+
async function parallelExecute(atomIds, options = {}) {
|
|
363
363
|
const cwd = process.cwd();
|
|
364
364
|
const manager = new WorktreeManager(cwd);
|
|
365
365
|
console.log(chalk.blue(`
|
|
@@ -397,7 +397,11 @@ async function parallelExecute(atomIds) {
|
|
|
397
397
|
execution.startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
398
398
|
await saveParallelState(cwd, state);
|
|
399
399
|
return new Promise((resolve) => {
|
|
400
|
-
const
|
|
400
|
+
const args = [process.argv[1] ?? "archon", "execute", execution.atomId];
|
|
401
|
+
if (options.skipGates) {
|
|
402
|
+
args.push("--skip-gates");
|
|
403
|
+
}
|
|
404
|
+
const child = spawn(process.execPath, args, {
|
|
401
405
|
cwd: execution.worktreePath,
|
|
402
406
|
stdio: "pipe"
|
|
403
407
|
});
|
|
@@ -1,13 +1,32 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SUPABASE_ANON_KEY,
|
|
3
|
+
SUPABASE_URL
|
|
4
|
+
} from "./chunk-M4LGRTLC.js";
|
|
5
|
+
|
|
1
6
|
// src/cli/config.ts
|
|
2
7
|
import { homedir } from "os";
|
|
3
8
|
import { join } from "path";
|
|
4
9
|
import { readFile, writeFile, mkdir, chmod, unlink } from "fs/promises";
|
|
5
10
|
import { existsSync } from "fs";
|
|
11
|
+
|
|
12
|
+
// src/core/supabase/client.ts
|
|
6
13
|
import { createClient } from "@supabase/supabase-js";
|
|
14
|
+
function createPkceSupabaseClient(supabaseUrl, supabaseAnonKey) {
|
|
15
|
+
return createClient(supabaseUrl, supabaseAnonKey, {
|
|
16
|
+
auth: {
|
|
17
|
+
flowType: "pkce"
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
function createAuthedSupabaseClient(supabaseUrl, supabaseAnonKey, accessToken) {
|
|
22
|
+
return createClient(supabaseUrl, supabaseAnonKey, {
|
|
23
|
+
global: { headers: { Authorization: `Bearer ${accessToken}` } }
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// src/cli/config.ts
|
|
7
28
|
var CONFIG_DIR = join(homedir(), ".archon");
|
|
8
29
|
var CONFIG_FILE = join(CONFIG_DIR, "config.json");
|
|
9
|
-
var SUPABASE_URL = "https://yjdkcepktrbabmzhcmrt.supabase.co";
|
|
10
|
-
var SUPABASE_ANON_KEY = "sb_publishable_XSGLVPfLZx-HA2uL6xsGCQ_KjAx2TIa";
|
|
11
30
|
function getAuthToken(config) {
|
|
12
31
|
return config.accessToken;
|
|
13
32
|
}
|
|
@@ -72,9 +91,7 @@ async function refreshSession(config) {
|
|
|
72
91
|
return false;
|
|
73
92
|
}
|
|
74
93
|
try {
|
|
75
|
-
const supabase =
|
|
76
|
-
auth: { flowType: "pkce" }
|
|
77
|
-
});
|
|
94
|
+
const supabase = createPkceSupabaseClient(SUPABASE_URL, SUPABASE_ANON_KEY);
|
|
78
95
|
const { data, error } = await supabase.auth.refreshSession({
|
|
79
96
|
refresh_token: config.refreshToken
|
|
80
97
|
});
|
|
@@ -112,6 +129,8 @@ async function getCurrentUser() {
|
|
|
112
129
|
}
|
|
113
130
|
|
|
114
131
|
export {
|
|
132
|
+
createPkceSupabaseClient,
|
|
133
|
+
createAuthedSupabaseClient,
|
|
115
134
|
getAuthToken,
|
|
116
135
|
getApiUrl,
|
|
117
136
|
loadConfig,
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
import {
|
|
8
8
|
loadConfig,
|
|
9
9
|
saveConfig
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-SUGIWSCB.js";
|
|
11
11
|
|
|
12
12
|
// src/cli/keys.ts
|
|
13
13
|
import chalk from "chalk";
|
|
@@ -24,10 +24,20 @@ async function promptForKey(provider) {
|
|
|
24
24
|
});
|
|
25
25
|
return new Promise((resolve) => {
|
|
26
26
|
const providerName = provider.charAt(0).toUpperCase() + provider.slice(1);
|
|
27
|
+
const rlAny = rl;
|
|
28
|
+
const originalWrite = rlAny._writeToOutput?.bind(rlAny);
|
|
29
|
+
rlAny._writeToOutput = (stringToWrite) => {
|
|
30
|
+
if (rlAny.stdoutMuted) {
|
|
31
|
+
rl.output.write("*");
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
originalWrite?.(stringToWrite);
|
|
35
|
+
};
|
|
27
36
|
rl.question(`Enter your ${providerName} API key: `, (answer) => {
|
|
28
37
|
rl.close();
|
|
29
38
|
resolve(answer.trim());
|
|
30
39
|
});
|
|
40
|
+
rlAny.stdoutMuted = true;
|
|
31
41
|
});
|
|
32
42
|
}
|
|
33
43
|
async function addKey(provider, options = {}) {
|