archondev 2.17.0 → 2.18.2
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 +1 -0
- package/dist/a11y-O35BAA25.js +14 -0
- package/dist/auth-HQBAG4CR.js +14 -0
- package/dist/bug-5WRBCFRT.js +12 -0
- package/dist/{chunk-ER4ADSWH.js → chunk-2NSWZDP7.js} +1 -156
- package/dist/chunk-3ASILTFB.js +73 -0
- package/dist/{chunk-LHCXE6UL.js → chunk-3PZ7WU5I.js} +26 -73
- package/dist/{chunk-QGM4M3NI.js → chunk-4VNS5WPM.js} +5 -0
- package/dist/chunk-4YEJ26F7.js +183 -0
- package/dist/chunk-5CFGPXQ3.js +160 -0
- package/dist/{chunk-TRLP7RMZ.js → chunk-75J2JMU3.js} +2 -2
- package/dist/{chunk-FGH2UX3E.js → chunk-BFPWDOMA.js} +1 -1
- package/dist/{chunk-FA2GAZ7L.js → chunk-CZCY63EY.js} +12 -8
- package/dist/{chunk-E7ZTIAQM.js → chunk-EKU62MGC.js} +160 -286
- package/dist/chunk-FWLLGLD5.js +353 -0
- package/dist/{chunk-BDPGWWQC.js → chunk-HGLPIM7J.js} +1 -1
- package/dist/{chunk-NIKN37AY.js → chunk-HJARQDQR.js} +1 -1
- package/dist/chunk-JF7JCK6H.js +485 -0
- package/dist/{chunk-DUJOT5B6.js → chunk-LBBHM4I5.js} +8 -8
- package/dist/{chunk-LPSS2U5V.js → chunk-NCPHO54C.js} +65 -2
- package/dist/{chunk-WZIRUPMP.js → chunk-NJF6MRTR.js} +1 -1
- package/dist/{chunk-54ATBLYE.js → chunk-P666JE3G.js} +1 -1
- package/dist/{chunk-SUGIWSCB.js → chunk-SVU7MLG6.js} +5 -24
- package/dist/chunk-UD45ZLV3.js +495 -0
- package/dist/{chunk-LXXTCZ2Q.js → chunk-UFR2LX6G.js} +216 -14
- package/dist/{chunk-2QIXLBAC.js → chunk-VF2OTDMS.js} +6 -4
- package/dist/{chunk-HTJOCKVV.js → chunk-ZJXIOETW.js} +6 -6
- package/dist/{code-review-ORCNXANW.js → code-review-6MU4UE5M.js} +4 -4
- package/dist/{config-USLUSE4N.js → config-JBPM2YAB.js} +2 -3
- package/dist/{constants-AHP5F7HW.js → constants-XDIWFFPN.js} +1 -1
- package/dist/execute-MB4ZF3HQ.js +18 -0
- package/dist/geo-KV4IRGKN.js +20 -0
- package/dist/index.js +928 -1831
- package/dist/{init-PSMJLDEZ.js → init-FINETS3Q.js} +2 -2
- package/dist/{interviewer-Q6PFSAGT.js → interviewer-NQHNMVH4.js} +5 -6
- package/dist/{keys-SXJ6MKPY.js → keys-THCHXIFD.js} +1 -1
- package/dist/{keys-VLK3EWSN.js → keys-U4QZE5YB.js} +3 -4
- package/dist/list-CNKAH354.js +17 -0
- package/dist/{manager-32P6ZZBP.js → manager-YSNTH2DG.js} +1 -1
- package/dist/models-UTFGCHAY.js +33 -0
- package/dist/{orchestration-X6LHSHBJ.js → orchestration-HIF3KP25.js} +1 -1
- package/dist/{parallel-WHFKRBPR.js → parallel-W2ETYYAL.js} +11 -7
- package/dist/{parser-4KJH2PT5.js → parser-BFHETZ5B.js} +1 -1
- package/dist/{plan-X77BUKNE.js → plan-XALA4SLH.js} +7 -6
- package/dist/{preferences-TWEK2RWY.js → preferences-I6WETXOI.js} +6 -6
- package/dist/{review-T4ID2QUF.js → review-AUG6GIL6.js} +5 -5
- package/dist/seo-PMI42KRZ.js +10 -0
- package/dist/{tier-selection-Z2RFHZUX.js → tier-selection-426HA765.js} +3 -4
- package/dist/web-checks-4BSYXWDF.js +13 -0
- package/package.json +1 -1
- package/dist/auth-KUFS3PBS.js +0 -14
- package/dist/bug-BJH4X5LI.js +0 -12
- package/dist/execute-73QW4ZEZ.js +0 -16
- package/dist/list-MMKB5TGX.js +0 -16
package/README.md
CHANGED
|
@@ -90,6 +90,7 @@ Copy governance files into any project. Works with your existing AI tools: **Cur
|
|
|
90
90
|
| `archon session resume [id]` | Resume session on another device |
|
|
91
91
|
| `archon execute ATOM --cloud` | Execute in cloud (creates PR when done) |
|
|
92
92
|
| `archon cloud status` | List cloud executions |
|
|
93
|
+
| `archon parallel cloud ATOM-001 ATOM-002` | Queue multiple atoms for cloud execution (Credits tier) |
|
|
93
94
|
| `archon index init [--local\|--cloud]` | Initialize semantic indexing |
|
|
94
95
|
| `archon index update [--cloud]` | Index changed files |
|
|
95
96
|
| `archon index search "query" [--cloud]` | Semantic code search |
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import {
|
|
2
|
+
bugReport
|
|
3
|
+
} from "./chunk-VF2OTDMS.js";
|
|
4
|
+
import "./chunk-5CFGPXQ3.js";
|
|
5
|
+
import "./chunk-2NSWZDP7.js";
|
|
6
|
+
import "./chunk-HJARQDQR.js";
|
|
7
|
+
import "./chunk-UFR2LX6G.js";
|
|
8
|
+
import "./chunk-SVU7MLG6.js";
|
|
9
|
+
import "./chunk-4VNS5WPM.js";
|
|
10
|
+
export {
|
|
11
|
+
bugReport
|
|
12
|
+
};
|
|
@@ -1,159 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AnthropicClient,
|
|
3
|
-
generateId,
|
|
4
3
|
getDefaultModel
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
|
|
7
|
-
// src/core/atoms/types.ts
|
|
8
|
-
var ATOM_TRANSITIONS = {
|
|
9
|
-
DRAFT: ["READY"],
|
|
10
|
-
READY: ["IN_PROGRESS", "BLOCKED"],
|
|
11
|
-
IN_PROGRESS: ["TESTING", "FAILED"],
|
|
12
|
-
TESTING: ["DONE", "FAILED"],
|
|
13
|
-
DONE: [],
|
|
14
|
-
// Terminal state
|
|
15
|
-
FAILED: ["IN_PROGRESS", "BLOCKED"],
|
|
16
|
-
// Can retry or escalate
|
|
17
|
-
BLOCKED: ["READY"]
|
|
18
|
-
// Can unblock and retry
|
|
19
|
-
};
|
|
20
|
-
var MAX_RETRIES = 3;
|
|
21
|
-
|
|
22
|
-
// src/core/atoms/atoms.ts
|
|
23
|
-
var MAX_RETRIES2 = MAX_RETRIES;
|
|
24
|
-
var atomCounter = 0;
|
|
25
|
-
function generateAtomId() {
|
|
26
|
-
atomCounter++;
|
|
27
|
-
return `ATOM-${String(atomCounter).padStart(3, "0")}`;
|
|
28
|
-
}
|
|
29
|
-
function createAtom(input, context) {
|
|
30
|
-
const now = /* @__PURE__ */ new Date();
|
|
31
|
-
const externalId = generateAtomId();
|
|
32
|
-
return {
|
|
33
|
-
id: generateId("atom"),
|
|
34
|
-
externalId,
|
|
35
|
-
title: input.title,
|
|
36
|
-
description: input.description ?? null,
|
|
37
|
-
goals: input.goals ?? [],
|
|
38
|
-
acceptanceCriteria: input.acceptanceCriteria,
|
|
39
|
-
ownershipPaths: input.ownershipPaths ?? [],
|
|
40
|
-
status: "DRAFT",
|
|
41
|
-
priority: input.priority ?? 100,
|
|
42
|
-
plan: null,
|
|
43
|
-
diffContract: null,
|
|
44
|
-
retryCount: 0,
|
|
45
|
-
errorMessage: null,
|
|
46
|
-
tags: input.tags ?? [],
|
|
47
|
-
metadata: input.metadata ?? {},
|
|
48
|
-
context: context ?? {},
|
|
49
|
-
createdAt: now,
|
|
50
|
-
updatedAt: now
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
function validateAtom(atom) {
|
|
54
|
-
const errors = [];
|
|
55
|
-
if (!atom.title || atom.title.trim() === "") {
|
|
56
|
-
errors.push({
|
|
57
|
-
field: "title",
|
|
58
|
-
message: "Title is required",
|
|
59
|
-
code: "REQUIRED"
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
if (!atom.acceptanceCriteria || atom.acceptanceCriteria.length === 0) {
|
|
63
|
-
errors.push({
|
|
64
|
-
field: "acceptanceCriteria",
|
|
65
|
-
message: "At least one acceptance criterion is required",
|
|
66
|
-
code: "REQUIRED"
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
atom.acceptanceCriteria.forEach((criterion, index) => {
|
|
70
|
-
if (typeof criterion !== "string" || criterion.trim() === "") {
|
|
71
|
-
errors.push({
|
|
72
|
-
field: `acceptanceCriteria[${index}]`,
|
|
73
|
-
message: "Acceptance criterion must be a non-empty string",
|
|
74
|
-
code: "INVALID_FORMAT"
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
if (atom.priority < 0) {
|
|
79
|
-
errors.push({
|
|
80
|
-
field: "priority",
|
|
81
|
-
message: "Priority must be a non-negative number",
|
|
82
|
-
code: "INVALID_VALUE"
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
const validStatuses = [
|
|
86
|
-
"DRAFT",
|
|
87
|
-
"READY",
|
|
88
|
-
"IN_PROGRESS",
|
|
89
|
-
"TESTING",
|
|
90
|
-
"DONE",
|
|
91
|
-
"FAILED",
|
|
92
|
-
"BLOCKED"
|
|
93
|
-
];
|
|
94
|
-
if (!validStatuses.includes(atom.status)) {
|
|
95
|
-
errors.push({
|
|
96
|
-
field: "status",
|
|
97
|
-
message: `Invalid status: ${atom.status}`,
|
|
98
|
-
code: "INVALID_VALUE"
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
return {
|
|
102
|
-
valid: errors.length === 0,
|
|
103
|
-
errors
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
function validateTransition(currentStatus, newStatus) {
|
|
107
|
-
const allowedTransitions = ATOM_TRANSITIONS[currentStatus];
|
|
108
|
-
if (!allowedTransitions) {
|
|
109
|
-
return {
|
|
110
|
-
valid: false,
|
|
111
|
-
errors: [
|
|
112
|
-
{
|
|
113
|
-
field: "status",
|
|
114
|
-
message: `Unknown current status: ${currentStatus}`,
|
|
115
|
-
code: "INVALID_VALUE"
|
|
116
|
-
}
|
|
117
|
-
]
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
if (!allowedTransitions.includes(newStatus)) {
|
|
121
|
-
return {
|
|
122
|
-
valid: false,
|
|
123
|
-
errors: [
|
|
124
|
-
{
|
|
125
|
-
field: "status",
|
|
126
|
-
message: `Cannot transition from ${currentStatus} to ${newStatus}. Allowed: ${allowedTransitions.join(", ") || "none"}`,
|
|
127
|
-
code: "INVALID_TRANSITION"
|
|
128
|
-
}
|
|
129
|
-
]
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
return { valid: true, errors: [] };
|
|
133
|
-
}
|
|
134
|
-
function transitionAtom(atom, newStatus, errorMessage) {
|
|
135
|
-
const validation = validateTransition(atom.status, newStatus);
|
|
136
|
-
if (!validation.valid) {
|
|
137
|
-
const error = validation.errors[0];
|
|
138
|
-
throw new Error(error?.message ?? "Invalid transition");
|
|
139
|
-
}
|
|
140
|
-
const now = /* @__PURE__ */ new Date();
|
|
141
|
-
const updates = {
|
|
142
|
-
status: newStatus,
|
|
143
|
-
updatedAt: now
|
|
144
|
-
};
|
|
145
|
-
if (newStatus === "FAILED") {
|
|
146
|
-
updates.retryCount = atom.retryCount + 1;
|
|
147
|
-
updates.errorMessage = errorMessage ?? null;
|
|
148
|
-
if (updates.retryCount >= MAX_RETRIES2) {
|
|
149
|
-
updates.status = "BLOCKED";
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
if (newStatus === "IN_PROGRESS" && atom.status === "FAILED") {
|
|
153
|
-
updates.errorMessage = null;
|
|
154
|
-
}
|
|
155
|
-
return { ...atom, ...updates };
|
|
156
|
-
}
|
|
4
|
+
} from "./chunk-HJARQDQR.js";
|
|
157
5
|
|
|
158
6
|
// src/agents/architect.ts
|
|
159
7
|
import { readFile } from "fs/promises";
|
|
@@ -367,8 +215,5 @@ var ArchitectAgent = class {
|
|
|
367
215
|
};
|
|
368
216
|
|
|
369
217
|
export {
|
|
370
|
-
createAtom,
|
|
371
|
-
validateAtom,
|
|
372
|
-
transitionAtom,
|
|
373
218
|
ArchitectAgent
|
|
374
219
|
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// src/cli/web-checks.ts
|
|
2
|
+
import { existsSync } from "fs";
|
|
3
|
+
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
4
|
+
import { join } from "path";
|
|
5
|
+
import yaml from "yaml";
|
|
6
|
+
var CONFIG_PATH = ".archon/config.yaml";
|
|
7
|
+
function ensureWebChecks(config) {
|
|
8
|
+
if (!config.webChecks) {
|
|
9
|
+
config.webChecks = {};
|
|
10
|
+
}
|
|
11
|
+
if (!config.webChecks.promptMode) {
|
|
12
|
+
config.webChecks.promptMode = "ask";
|
|
13
|
+
}
|
|
14
|
+
if (!config.webChecks.lastRun) {
|
|
15
|
+
config.webChecks.lastRun = {};
|
|
16
|
+
}
|
|
17
|
+
return config.webChecks;
|
|
18
|
+
}
|
|
19
|
+
async function loadLocalConfig(cwd) {
|
|
20
|
+
const configPath = join(cwd, CONFIG_PATH);
|
|
21
|
+
if (!existsSync(configPath)) {
|
|
22
|
+
return {};
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
const content = await readFile(configPath, "utf-8");
|
|
26
|
+
return yaml.parse(content) ?? {};
|
|
27
|
+
} catch {
|
|
28
|
+
return {};
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
async function saveLocalConfig(cwd, config) {
|
|
32
|
+
const configPath = join(cwd, CONFIG_PATH);
|
|
33
|
+
const archonDir = join(cwd, ".archon");
|
|
34
|
+
if (!existsSync(archonDir)) {
|
|
35
|
+
await mkdir(archonDir, { recursive: true });
|
|
36
|
+
}
|
|
37
|
+
await writeFile(configPath, yaml.stringify(config), "utf-8");
|
|
38
|
+
}
|
|
39
|
+
async function loadWebChecks(cwd) {
|
|
40
|
+
const config = await loadLocalConfig(cwd);
|
|
41
|
+
return ensureWebChecks(config);
|
|
42
|
+
}
|
|
43
|
+
async function setWebPromptMode(cwd, mode) {
|
|
44
|
+
const config = await loadLocalConfig(cwd);
|
|
45
|
+
const webChecks = ensureWebChecks(config);
|
|
46
|
+
webChecks.promptMode = mode;
|
|
47
|
+
await saveLocalConfig(cwd, config);
|
|
48
|
+
}
|
|
49
|
+
async function recordWebCheckResult(cwd, type, passed) {
|
|
50
|
+
const config = await loadLocalConfig(cwd);
|
|
51
|
+
const webChecks = ensureWebChecks(config);
|
|
52
|
+
if (!webChecks.lastRun) {
|
|
53
|
+
webChecks.lastRun = {};
|
|
54
|
+
}
|
|
55
|
+
webChecks.lastRun[type] = {
|
|
56
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
57
|
+
passed
|
|
58
|
+
};
|
|
59
|
+
await saveLocalConfig(cwd, config);
|
|
60
|
+
}
|
|
61
|
+
function formatWebCheckStatus(run) {
|
|
62
|
+
if (!run) return "Never run";
|
|
63
|
+
const date = new Date(run.timestamp);
|
|
64
|
+
const formatted = isNaN(date.getTime()) ? run.timestamp : `${date.toLocaleDateString()} ${date.toLocaleTimeString()}`;
|
|
65
|
+
return `${run.passed ? "Passed" : "Issues found"} \u2022 ${formatted}`;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export {
|
|
69
|
+
loadWebChecks,
|
|
70
|
+
setWebPromptMode,
|
|
71
|
+
recordWebCheckResult,
|
|
72
|
+
formatWebCheckStatus
|
|
73
|
+
};
|
|
@@ -2,33 +2,35 @@ import {
|
|
|
2
2
|
ArchitectureParser
|
|
3
3
|
} from "./chunk-5EVHUDQX.js";
|
|
4
4
|
import {
|
|
5
|
-
ArchitectAgent,
|
|
6
5
|
createAtom,
|
|
7
6
|
validateAtom
|
|
8
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-5CFGPXQ3.js";
|
|
8
|
+
import {
|
|
9
|
+
ArchitectAgent
|
|
10
|
+
} from "./chunk-2NSWZDP7.js";
|
|
9
11
|
import {
|
|
10
12
|
AnthropicClient,
|
|
11
13
|
getDefaultModel
|
|
12
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-HJARQDQR.js";
|
|
13
15
|
import {
|
|
14
16
|
KeyManager
|
|
15
17
|
} from "./chunk-RDG5BUED.js";
|
|
16
|
-
import {
|
|
17
|
-
createAuthedSupabaseClient,
|
|
18
|
-
isAuthenticated,
|
|
19
|
-
loadConfig
|
|
20
|
-
} from "./chunk-SUGIWSCB.js";
|
|
21
18
|
import {
|
|
22
19
|
SUPABASE_ANON_KEY,
|
|
23
20
|
SUPABASE_URL
|
|
24
21
|
} from "./chunk-M4LGRTLC.js";
|
|
22
|
+
import {
|
|
23
|
+
isAuthenticated,
|
|
24
|
+
loadConfig
|
|
25
|
+
} from "./chunk-SVU7MLG6.js";
|
|
25
26
|
|
|
26
27
|
// src/cli/plan.ts
|
|
27
28
|
import chalk from "chalk";
|
|
28
|
-
import { existsSync
|
|
29
|
-
import { readFile
|
|
30
|
-
import { join
|
|
29
|
+
import { existsSync } from "fs";
|
|
30
|
+
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
31
|
+
import { join } from "path";
|
|
31
32
|
import { createInterface } from "readline";
|
|
33
|
+
import { createClient } from "@supabase/supabase-js";
|
|
32
34
|
|
|
33
35
|
// src/agents/sentinel.ts
|
|
34
36
|
var SYSTEM_PROMPT = `You are the Sentinel, a paranoid and skeptical code reviewer responsible for finding issues in implementation plans.
|
|
@@ -732,31 +734,6 @@ var TrackedAdversarialPlanner = class {
|
|
|
732
734
|
}
|
|
733
735
|
};
|
|
734
736
|
|
|
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
|
-
|
|
760
737
|
// src/cli/plan.ts
|
|
761
738
|
var ATOMS_DIR = ".archon/atoms";
|
|
762
739
|
function createPrompt() {
|
|
@@ -778,8 +755,8 @@ async function plan(description, options) {
|
|
|
778
755
|
console.log(chalk.yellow('Not authenticated. Run "archon login" first.'));
|
|
779
756
|
console.log(chalk.dim("For local development, you can continue without authentication."));
|
|
780
757
|
}
|
|
781
|
-
const archPath =
|
|
782
|
-
if (!
|
|
758
|
+
const archPath = join(process.cwd(), "ARCHITECTURE.md");
|
|
759
|
+
if (!existsSync(archPath)) {
|
|
783
760
|
console.error(chalk.red('ARCHITECTURE.md not found. Run "archon init" first.'));
|
|
784
761
|
process.exit(1);
|
|
785
762
|
}
|
|
@@ -804,26 +781,6 @@ async function plan(description, options) {
|
|
|
804
781
|
}
|
|
805
782
|
process.exit(1);
|
|
806
783
|
}
|
|
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
|
-
}
|
|
827
784
|
console.log(chalk.blue(`
|
|
828
785
|
Atom created: ${atom.externalId}`));
|
|
829
786
|
console.log(chalk.dim(`Title: ${atom.title}`));
|
|
@@ -849,17 +806,14 @@ Atom saved: ${atom.externalId}`));
|
|
|
849
806
|
console.log(chalk.dim("Architect will generate a plan, Sentinel will validate it.\n"));
|
|
850
807
|
const config = await loadConfig();
|
|
851
808
|
let billingContext;
|
|
852
|
-
if (config.userId
|
|
853
|
-
const supabase =
|
|
809
|
+
if (config.userId) {
|
|
810
|
+
const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY);
|
|
854
811
|
billingContext = {
|
|
855
812
|
userId: config.userId,
|
|
856
813
|
supabase
|
|
857
814
|
};
|
|
858
815
|
}
|
|
859
|
-
const
|
|
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 });
|
|
816
|
+
const planner = billingContext ? new TrackedAdversarialPlanner({ apiKey, billing: billingContext }) : new AdversarialPlanner({ apiKey });
|
|
863
817
|
if (billingContext && planner instanceof TrackedAdversarialPlanner) {
|
|
864
818
|
const balanceCheck = await planner.checkBalance();
|
|
865
819
|
if (!balanceCheck.sufficient && balanceCheck.tier === "CREDITS") {
|
|
@@ -973,24 +927,24 @@ function displayPlan(plan2) {
|
|
|
973
927
|
console.log(chalk.bold("\nComplexity:"), plan2.estimated_complexity);
|
|
974
928
|
}
|
|
975
929
|
async function saveAtom(atom) {
|
|
976
|
-
const atomsDir =
|
|
977
|
-
if (!
|
|
930
|
+
const atomsDir = join(process.cwd(), ATOMS_DIR);
|
|
931
|
+
if (!existsSync(atomsDir)) {
|
|
978
932
|
await mkdir(atomsDir, { recursive: true });
|
|
979
933
|
}
|
|
980
|
-
const atomFile =
|
|
934
|
+
const atomFile = join(atomsDir, `${atom.externalId}.json`);
|
|
981
935
|
await writeFile(atomFile, JSON.stringify(atom, null, 2));
|
|
982
936
|
}
|
|
983
937
|
async function loadAtom(atomId) {
|
|
984
|
-
const atomFile =
|
|
985
|
-
if (!
|
|
938
|
+
const atomFile = join(process.cwd(), ATOMS_DIR, `${atomId}.json`);
|
|
939
|
+
if (!existsSync(atomFile)) {
|
|
986
940
|
return null;
|
|
987
941
|
}
|
|
988
|
-
const content = await
|
|
942
|
+
const content = await readFile(atomFile, "utf-8");
|
|
989
943
|
return JSON.parse(content);
|
|
990
944
|
}
|
|
991
945
|
async function listLocalAtoms() {
|
|
992
|
-
const atomsDir =
|
|
993
|
-
if (!
|
|
946
|
+
const atomsDir = join(process.cwd(), ATOMS_DIR);
|
|
947
|
+
if (!existsSync(atomsDir)) {
|
|
994
948
|
return [];
|
|
995
949
|
}
|
|
996
950
|
const { readdir } = await import("fs/promises");
|
|
@@ -1009,7 +963,6 @@ async function listLocalAtoms() {
|
|
|
1009
963
|
|
|
1010
964
|
export {
|
|
1011
965
|
UsageRecorder,
|
|
1012
|
-
loadRoleOverrides,
|
|
1013
966
|
plan,
|
|
1014
967
|
parseAtomDescription,
|
|
1015
968
|
loadAtom,
|
|
@@ -13,6 +13,10 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
13
13
|
var __commonJS = (cb, mod) => function __require2() {
|
|
14
14
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
15
15
|
};
|
|
16
|
+
var __export = (target, all) => {
|
|
17
|
+
for (var name in all)
|
|
18
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
19
|
+
};
|
|
16
20
|
var __copyProps = (to, from, except, desc) => {
|
|
17
21
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
18
22
|
for (let key of __getOwnPropNames(from))
|
|
@@ -33,5 +37,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
33
37
|
export {
|
|
34
38
|
__require,
|
|
35
39
|
__commonJS,
|
|
40
|
+
__export,
|
|
36
41
|
__toESM
|
|
37
42
|
};
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SUPABASE_ANON_KEY,
|
|
3
|
+
SUPABASE_URL
|
|
4
|
+
} from "./chunk-M4LGRTLC.js";
|
|
5
|
+
import {
|
|
6
|
+
getAuthToken,
|
|
7
|
+
loadConfig
|
|
8
|
+
} from "./chunk-SVU7MLG6.js";
|
|
9
|
+
|
|
10
|
+
// src/core/supabase/client.ts
|
|
11
|
+
import { createClient } from "@supabase/supabase-js";
|
|
12
|
+
function createAuthedSupabaseClient(supabaseUrl, supabaseAnonKey, accessToken) {
|
|
13
|
+
return createClient(supabaseUrl, supabaseAnonKey, {
|
|
14
|
+
global: { headers: { Authorization: `Bearer ${accessToken}` } }
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// src/cli/cloud.ts
|
|
19
|
+
import chalk from "chalk";
|
|
20
|
+
function getClient(accessToken) {
|
|
21
|
+
return createAuthedSupabaseClient(SUPABASE_URL, SUPABASE_ANON_KEY, accessToken);
|
|
22
|
+
}
|
|
23
|
+
async function cloudStatus() {
|
|
24
|
+
const config = await loadConfig();
|
|
25
|
+
const authToken = getAuthToken(config);
|
|
26
|
+
if (!authToken) {
|
|
27
|
+
console.error(chalk.red('Not authenticated. Run "archon login" first.'));
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
const client = getClient(authToken);
|
|
31
|
+
const { data, error } = await client.from("cloud_executions").select("*").order("created_at", { ascending: false }).limit(20);
|
|
32
|
+
if (error) {
|
|
33
|
+
console.error(chalk.red("Failed to fetch cloud executions:"), error.message);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
if (!data || data.length === 0) {
|
|
37
|
+
console.log(chalk.dim("No cloud executions found."));
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
console.log(chalk.bold("\nCloud Executions:\n"));
|
|
41
|
+
for (const exec of data) {
|
|
42
|
+
const statusIcon = getStatusIcon(exec.status);
|
|
43
|
+
const duration = exec.compute_minutes ? `${exec.compute_minutes} min` : "-";
|
|
44
|
+
console.log(`${statusIcon} ${chalk.bold(exec.id.slice(0, 8))} - ${exec.atom_id}`);
|
|
45
|
+
console.log(chalk.dim(` Project: ${exec.project_name ?? "unknown"}`));
|
|
46
|
+
console.log(chalk.dim(` Status: ${exec.status} | Duration: ${duration}`));
|
|
47
|
+
if (exec.result_branch) {
|
|
48
|
+
console.log(chalk.dim(` Branch: ${exec.result_branch}`));
|
|
49
|
+
}
|
|
50
|
+
if (exec.result_pr_url) {
|
|
51
|
+
console.log(chalk.dim(` PR: ${exec.result_pr_url}`));
|
|
52
|
+
}
|
|
53
|
+
if (exec.error_message) {
|
|
54
|
+
console.log(chalk.red(` Error: ${exec.error_message}`));
|
|
55
|
+
}
|
|
56
|
+
console.log();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
async function cloudCancel(executionId) {
|
|
60
|
+
const config = await loadConfig();
|
|
61
|
+
const authToken = getAuthToken(config);
|
|
62
|
+
if (!authToken) {
|
|
63
|
+
console.error(chalk.red('Not authenticated. Run "archon login" first.'));
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
const client = getClient(authToken);
|
|
67
|
+
const { data: existing, error: fetchError } = await client.from("cloud_executions").select("id, status").eq("id", executionId).single();
|
|
68
|
+
if (fetchError || !existing) {
|
|
69
|
+
console.error(chalk.red(`Execution ${executionId} not found.`));
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
if (existing.status === "completed" || existing.status === "failed" || existing.status === "cancelled") {
|
|
73
|
+
console.log(chalk.yellow(`Execution is already ${existing.status}. Cannot cancel.`));
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const { error } = await client.from("cloud_executions").update({ status: "cancelled" }).eq("id", executionId);
|
|
77
|
+
if (error) {
|
|
78
|
+
console.error(chalk.red("Failed to cancel execution:"), error.message);
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
console.log(chalk.green(`\u2713 Execution ${executionId.slice(0, 8)} cancelled.`));
|
|
82
|
+
}
|
|
83
|
+
async function cloudLogs(executionId) {
|
|
84
|
+
const config = await loadConfig();
|
|
85
|
+
const authToken = getAuthToken(config);
|
|
86
|
+
if (!authToken) {
|
|
87
|
+
console.error(chalk.red('Not authenticated. Run "archon login" first.'));
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
90
|
+
const client = getClient(authToken);
|
|
91
|
+
const { data, error } = await client.from("cloud_executions").select("id, atom_id, status, logs").eq("id", executionId).single();
|
|
92
|
+
if (error || !data) {
|
|
93
|
+
console.error(chalk.red(`Execution ${executionId} not found.`));
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
const exec = data;
|
|
97
|
+
console.log(chalk.bold(`
|
|
98
|
+
Logs for ${exec.id.slice(0, 8)} (${exec.atom_id}):
|
|
99
|
+
`));
|
|
100
|
+
console.log(chalk.dim(`Status: ${exec.status}
|
|
101
|
+
`));
|
|
102
|
+
const logs = exec.logs;
|
|
103
|
+
if (!logs || logs.length === 0) {
|
|
104
|
+
console.log(chalk.dim("No logs available yet."));
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
for (const log of logs) {
|
|
108
|
+
const ts = log.timestamp ? chalk.dim(`[${log.timestamp}]`) : "";
|
|
109
|
+
const level = log.level === "error" ? chalk.red("ERROR") : log.level === "warn" ? chalk.yellow("WARN") : chalk.dim("INFO");
|
|
110
|
+
console.log(`${ts} ${level} ${log.message}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
async function queueCloudExecution(atomId, projectName, options) {
|
|
114
|
+
const config = await loadConfig();
|
|
115
|
+
const authToken = getAuthToken(config);
|
|
116
|
+
if (!authToken) {
|
|
117
|
+
throw new Error('Not authenticated. Run "archon login" first.');
|
|
118
|
+
}
|
|
119
|
+
const client = getClient(authToken);
|
|
120
|
+
const insertData = {
|
|
121
|
+
atom_id: atomId,
|
|
122
|
+
project_name: projectName,
|
|
123
|
+
status: "queued"
|
|
124
|
+
};
|
|
125
|
+
if (options?.repoUrl) {
|
|
126
|
+
insertData["repo_url"] = options.repoUrl;
|
|
127
|
+
}
|
|
128
|
+
if (options?.repoBranch) {
|
|
129
|
+
insertData["repo_branch"] = options.repoBranch;
|
|
130
|
+
}
|
|
131
|
+
if (options?.atomData) {
|
|
132
|
+
insertData["atom_data"] = options.atomData;
|
|
133
|
+
}
|
|
134
|
+
const { data, error } = await client.from("cloud_executions").insert(insertData).select("id").single();
|
|
135
|
+
if (error) {
|
|
136
|
+
throw new Error(`Failed to queue execution: ${error.message}`);
|
|
137
|
+
}
|
|
138
|
+
return data.id;
|
|
139
|
+
}
|
|
140
|
+
async function getGitRemoteUrl(cwd = process.cwd()) {
|
|
141
|
+
try {
|
|
142
|
+
const { execSync } = await import("child_process");
|
|
143
|
+
const output = execSync("git remote get-url origin", { cwd, encoding: "utf-8" });
|
|
144
|
+
return output.trim();
|
|
145
|
+
} catch {
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
async function getGitBranch(cwd = process.cwd()) {
|
|
150
|
+
try {
|
|
151
|
+
const { execSync } = await import("child_process");
|
|
152
|
+
const output = execSync("git branch --show-current", { cwd, encoding: "utf-8" });
|
|
153
|
+
return output.trim() || "main";
|
|
154
|
+
} catch {
|
|
155
|
+
return "main";
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
function getStatusIcon(status) {
|
|
159
|
+
switch (status) {
|
|
160
|
+
case "queued":
|
|
161
|
+
return chalk.blue("\u23F3");
|
|
162
|
+
case "running":
|
|
163
|
+
return chalk.yellow("\u{1F504}");
|
|
164
|
+
case "completed":
|
|
165
|
+
return chalk.green("\u2713");
|
|
166
|
+
case "failed":
|
|
167
|
+
return chalk.red("\u2717");
|
|
168
|
+
case "cancelled":
|
|
169
|
+
return chalk.gray("\u2298");
|
|
170
|
+
default:
|
|
171
|
+
return chalk.dim("?");
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export {
|
|
176
|
+
createAuthedSupabaseClient,
|
|
177
|
+
cloudStatus,
|
|
178
|
+
cloudCancel,
|
|
179
|
+
cloudLogs,
|
|
180
|
+
queueCloudExecution,
|
|
181
|
+
getGitRemoteUrl,
|
|
182
|
+
getGitBranch
|
|
183
|
+
};
|