@codeagentswarm/cas-cloud 0.0.17 → 0.0.18
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/dist/antigravity-mcp-launcher.js +2 -2
- package/dist/cas.js +448 -19
- package/dist/mcp-stdio-server.js +2 -2
- package/package.json +1 -1
|
@@ -1068,7 +1068,7 @@ var require_database_mcp_standalone = __commonJS({
|
|
|
1068
1068
|
{ status_key: "needs_testing", label: "Needs testing", color: "#3b82f6", icon: "flask-conical", sort_order: 2, is_default: 1, agent_settable: 1, prompt: "Set it when you finish the implementation and the work is pending the user testing it manually. Do not set it if there are still things left to implement." },
|
|
1069
1069
|
{ status_key: "working", label: "Working", color: "#fbbf24", icon: "hammer", sort_order: 3, is_default: 1, agent_settable: 1, prompt: "Set it when you start working on any request and while you are implementing, investigating or fixing something." },
|
|
1070
1070
|
{ status_key: "done", label: "Done", color: "#22c55e", icon: "circle-check", sort_order: 4, is_default: 1, agent_settable: 1, prompt: "Set it when the work is completely finished: implemented, validated and with its commit/push done when applicable. It is the final state." },
|
|
1071
|
-
{ status_key: "idle", label: "Idle", color: "#6b7280", icon: "circle-dashed", sort_order: 5, is_default: 1, agent_settable: 0, prompt: "Set by the app
|
|
1071
|
+
{ status_key: "idle", label: "Idle", color: "#6b7280", icon: "circle-dashed", sort_order: 5, is_default: 1, agent_settable: 0, prompt: "Set by the app on an agent that has just been opened and has not been given any work yet. Agents cannot set this status; it clears itself as soon as you send the agent something." }
|
|
1072
1072
|
];
|
|
1073
1073
|
var IDLE_TERMINAL_STATUS_KEY = "idle";
|
|
1074
1074
|
var IDLE_STATUS_SEEDED_SETTING = "terminal_status_idle_seeded";
|
|
@@ -1081,7 +1081,7 @@ var require_database_mcp_standalone = __commonJS({
|
|
|
1081
1081
|
done: 6
|
|
1082
1082
|
};
|
|
1083
1083
|
var LEGACY_DEFAULT_PROMPTS = {
|
|
1084
|
-
idle: "Set by the app
|
|
1084
|
+
idle: "Set by the app when an agent is resting without an explicit work status, including after a reply finishes. It does not mean the work is complete or that user input is required. Agents cannot set this status.",
|
|
1085
1085
|
working: "Ponlo al empezar a trabajar en cualquier petici\xF3n y mientras est\xE9s implementando, investigando o arreglando algo.",
|
|
1086
1086
|
needs_input: "Ponlo cuando pares porque necesites una respuesta o decisi\xF3n del usuario para continuar (una pregunta, una elecci\xF3n de dise\xF1o, un permiso).",
|
|
1087
1087
|
needs_testing: "Ponlo cuando termines la implementaci\xF3n y el trabajo quede pendiente de que el usuario lo pruebe a mano. No lo pongas si a\xFAn quedan cosas por implementar.",
|
package/dist/cas.js
CHANGED
|
@@ -897,13 +897,14 @@ var require_provider_login_manager = __commonJS({
|
|
|
897
897
|
}
|
|
898
898
|
}
|
|
899
899
|
if (agent === "codex") {
|
|
900
|
-
const
|
|
900
|
+
const signedOut2 = /\bnot\s+(?:logged|signed)\s+in\b/i.test(output);
|
|
901
901
|
return {
|
|
902
|
-
loggedIn: !
|
|
902
|
+
loggedIn: !signedOut2 && /\b(?:logged|signed)\s+in\b/i.test(output),
|
|
903
903
|
detail: output.split("\n")[0] || ""
|
|
904
904
|
};
|
|
905
905
|
}
|
|
906
|
-
|
|
906
|
+
const signedOut = agent === "cursor" && /\bnot\s+(?:logged|signed)\s+in\b/i.test(output);
|
|
907
|
+
return { loggedIn: code === 0 && !signedOut, detail: output.split("\n")[0] || "" };
|
|
907
908
|
}
|
|
908
909
|
function safeRequireRegistry() {
|
|
909
910
|
try {
|
|
@@ -7574,7 +7575,7 @@ var require_codex_quota_reader = __commonJS({
|
|
|
7574
7575
|
* accountWide: { snapshot: object, accountWide: boolean }|null
|
|
7575
7576
|
* }|null>}
|
|
7576
7577
|
*/
|
|
7577
|
-
async readCandidatesFromFile(filePath, knownSessionId = null) {
|
|
7578
|
+
async readCandidatesFromFile(filePath, knownSessionId = null, { since = null } = {}) {
|
|
7578
7579
|
var _a;
|
|
7579
7580
|
try {
|
|
7580
7581
|
if (!filePath || !fs.existsSync(filePath)) return null;
|
|
@@ -7602,6 +7603,9 @@ var require_codex_quota_reader = __commonJS({
|
|
|
7602
7603
|
const parsed = JSON.parse(line.toString("utf8"));
|
|
7603
7604
|
const rateLimits = extractRateLimits(parsed);
|
|
7604
7605
|
if (!rateLimits) return false;
|
|
7606
|
+
if (since && parsed.timestamp && Date.parse(parsed.timestamp) < since) {
|
|
7607
|
+
return true;
|
|
7608
|
+
}
|
|
7605
7609
|
const windows = [];
|
|
7606
7610
|
const primary = bucketToWindow(rateLimits.primary);
|
|
7607
7611
|
if (primary) windows.push(primary);
|
|
@@ -7733,7 +7737,7 @@ var require_codex_quota_reader = __commonJS({
|
|
|
7733
7737
|
return null;
|
|
7734
7738
|
}
|
|
7735
7739
|
}
|
|
7736
|
-
async getQuotas(accountForSession, activeBindings = null) {
|
|
7740
|
+
async getQuotas(accountForSession, activeBindings = null, bindingSince = null) {
|
|
7737
7741
|
if (typeof accountForSession !== "function") {
|
|
7738
7742
|
const snapshot = await this.getQuota();
|
|
7739
7743
|
return snapshot ? [snapshot] : [];
|
|
@@ -7761,7 +7765,10 @@ var require_codex_quota_reader = __commonJS({
|
|
|
7761
7765
|
for (const [accountId, files] of boundFilesByAccount) {
|
|
7762
7766
|
let fallback = null;
|
|
7763
7767
|
for (const { file, sessionId } of files) {
|
|
7764
|
-
const
|
|
7768
|
+
const since = bindingSince && typeof bindingSince === "object" ? bindingSince[sessionId] : null;
|
|
7769
|
+
const candidates = await this.readCandidatesFromFile(file, sessionId, {
|
|
7770
|
+
since: Number.isFinite(since) ? since : null
|
|
7771
|
+
});
|
|
7765
7772
|
if (!candidates) continue;
|
|
7766
7773
|
if (candidates.accountWide && hasActiveWindow(candidates.accountWide.snapshot)) {
|
|
7767
7774
|
boundSnapshots.push({ ...candidates.accountWide.snapshot, accountId });
|
|
@@ -8000,16 +8007,18 @@ var require_codex_cli_strategy = __commonJS({
|
|
|
8000
8007
|
async getQuota() {
|
|
8001
8008
|
return getCodexQuotaReader().getInstance().getQuota();
|
|
8002
8009
|
}
|
|
8003
|
-
setQuotaAccountResolver(resolver, isEnabled = null, activeBindings = null) {
|
|
8010
|
+
setQuotaAccountResolver(resolver, isEnabled = null, activeBindings = null, bindingSince = null) {
|
|
8004
8011
|
this._quotaAccountResolver = typeof resolver === "function" ? resolver : null;
|
|
8005
8012
|
this._quotaAccountResolverEnabled = typeof isEnabled === "function" ? isEnabled : null;
|
|
8006
8013
|
this._quotaAccountBindings = typeof activeBindings === "function" ? activeBindings : null;
|
|
8014
|
+
this._quotaAccountBindingSince = typeof bindingSince === "function" ? bindingSince : null;
|
|
8007
8015
|
}
|
|
8008
8016
|
async getQuotas() {
|
|
8009
|
-
var _a, _b;
|
|
8017
|
+
var _a, _b, _c;
|
|
8010
8018
|
const resolver = ((_a = this._quotaAccountResolverEnabled) == null ? void 0 : _a.call(this)) === false ? null : this._quotaAccountResolver;
|
|
8011
8019
|
const bindings = resolver ? (_b = this._quotaAccountBindings) == null ? void 0 : _b.call(this) : null;
|
|
8012
|
-
|
|
8020
|
+
const bindingSince = (resolver ? (_c = this._quotaAccountBindingSince) == null ? void 0 : _c.call(this) : null) ?? null;
|
|
8021
|
+
return getCodexQuotaReader().getInstance().getQuotas(resolver, bindings, bindingSince);
|
|
8013
8022
|
}
|
|
8014
8023
|
// ========================================
|
|
8015
8024
|
// Detection Methods
|
|
@@ -27667,7 +27676,7 @@ var require_database_mcp_standalone = __commonJS({
|
|
|
27667
27676
|
{ status_key: "needs_testing", label: "Needs testing", color: "#3b82f6", icon: "flask-conical", sort_order: 2, is_default: 1, agent_settable: 1, prompt: "Set it when you finish the implementation and the work is pending the user testing it manually. Do not set it if there are still things left to implement." },
|
|
27668
27677
|
{ status_key: "working", label: "Working", color: "#fbbf24", icon: "hammer", sort_order: 3, is_default: 1, agent_settable: 1, prompt: "Set it when you start working on any request and while you are implementing, investigating or fixing something." },
|
|
27669
27678
|
{ status_key: "done", label: "Done", color: "#22c55e", icon: "circle-check", sort_order: 4, is_default: 1, agent_settable: 1, prompt: "Set it when the work is completely finished: implemented, validated and with its commit/push done when applicable. It is the final state." },
|
|
27670
|
-
{ status_key: "idle", label: "Idle", color: "#6b7280", icon: "circle-dashed", sort_order: 5, is_default: 1, agent_settable: 0, prompt: "Set by the app
|
|
27679
|
+
{ status_key: "idle", label: "Idle", color: "#6b7280", icon: "circle-dashed", sort_order: 5, is_default: 1, agent_settable: 0, prompt: "Set by the app on an agent that has just been opened and has not been given any work yet. Agents cannot set this status; it clears itself as soon as you send the agent something." }
|
|
27671
27680
|
];
|
|
27672
27681
|
var IDLE_TERMINAL_STATUS_KEY = "idle";
|
|
27673
27682
|
var IDLE_STATUS_SEEDED_SETTING = "terminal_status_idle_seeded";
|
|
@@ -27680,7 +27689,7 @@ var require_database_mcp_standalone = __commonJS({
|
|
|
27680
27689
|
done: 6
|
|
27681
27690
|
};
|
|
27682
27691
|
var LEGACY_DEFAULT_PROMPTS = {
|
|
27683
|
-
idle: "Set by the app
|
|
27692
|
+
idle: "Set by the app when an agent is resting without an explicit work status, including after a reply finishes. It does not mean the work is complete or that user input is required. Agents cannot set this status.",
|
|
27684
27693
|
working: "Ponlo al empezar a trabajar en cualquier petici\xF3n y mientras est\xE9s implementando, investigando o arreglando algo.",
|
|
27685
27694
|
needs_input: "Ponlo cuando pares porque necesites una respuesta o decisi\xF3n del usuario para continuar (una pregunta, una elecci\xF3n de dise\xF1o, un permiso).",
|
|
27686
27695
|
needs_testing: "Ponlo cuando termines la implementaci\xF3n y el trabajo quede pendiente de que el usuario lo pruebe a mano. No lo pongas si a\xFAn quedan cosas por implementar.",
|
|
@@ -35313,9 +35322,12 @@ var require_mobile_runtime = __commonJS({
|
|
|
35313
35322
|
workspaceGitCreate = null,
|
|
35314
35323
|
listProjects = null,
|
|
35315
35324
|
listProjectDirectories = null,
|
|
35325
|
+
listProjectLocations = null,
|
|
35326
|
+
addProjectLocation = null,
|
|
35316
35327
|
createProject = null,
|
|
35317
35328
|
updateProject = null,
|
|
35318
35329
|
gitAvailability = null,
|
|
35330
|
+
listGitHubRepositories = null,
|
|
35319
35331
|
projectIconAvailability = null,
|
|
35320
35332
|
generateProjectIcon = null,
|
|
35321
35333
|
registerProject = null,
|
|
@@ -35384,9 +35396,12 @@ var require_mobile_runtime = __commonJS({
|
|
|
35384
35396
|
this.workspaceGitCreate = workspaceGitCreate;
|
|
35385
35397
|
this.listProjects = listProjects;
|
|
35386
35398
|
this.listProjectDirectories = listProjectDirectories;
|
|
35399
|
+
this.listProjectLocations = listProjectLocations;
|
|
35400
|
+
this.addProjectLocation = addProjectLocation;
|
|
35387
35401
|
this.createProject = createProject;
|
|
35388
35402
|
this.updateProject = updateProject;
|
|
35389
35403
|
this.gitAvailability = gitAvailability;
|
|
35404
|
+
this.listGitHubRepositories = listGitHubRepositories;
|
|
35390
35405
|
this.projectIconAvailability = projectIconAvailability;
|
|
35391
35406
|
this.generateProjectIcon = generateProjectIcon;
|
|
35392
35407
|
this.registerProject = registerProject;
|
|
@@ -36502,6 +36517,7 @@ var require_mobile_runtime = __commonJS({
|
|
|
36502
36517
|
"tasks.list",
|
|
36503
36518
|
"projects.list",
|
|
36504
36519
|
"project.directories.list",
|
|
36520
|
+
"project.locations.list",
|
|
36505
36521
|
"providers.list",
|
|
36506
36522
|
"provider.login.describe",
|
|
36507
36523
|
"workspace.files.list",
|
|
@@ -36667,6 +36683,19 @@ var require_mobile_runtime = __commonJS({
|
|
|
36667
36683
|
relativePath: payload.relativePath
|
|
36668
36684
|
});
|
|
36669
36685
|
}
|
|
36686
|
+
if (["project.locations.list", "project.locations.add"].includes(command.type)) {
|
|
36687
|
+
const adding = command.type === "project.locations.add";
|
|
36688
|
+
exactPayload(adding ? ["locationId", "requestId"] : ["locationId", "offset"]);
|
|
36689
|
+
try {
|
|
36690
|
+
const result = adding ? await this.addProjectLocation({ locationId: payload.locationId, requestId: mutationRequestId() }) : await this.listProjectLocations(payload);
|
|
36691
|
+
if (adding) this.publishProjects();
|
|
36692
|
+
return result;
|
|
36693
|
+
} catch (error) {
|
|
36694
|
+
throw Object.assign(new Error("The remote location could not be read or saved."), {
|
|
36695
|
+
code: ["location_expired", "location_permission_denied"].includes(error.code) ? error.code : "location_unavailable"
|
|
36696
|
+
});
|
|
36697
|
+
}
|
|
36698
|
+
}
|
|
36670
36699
|
if (command.type === "project.create") {
|
|
36671
36700
|
if (typeof this.createProject !== "function") throw new Error("Remote project creation is unavailable");
|
|
36672
36701
|
exactPayload(["name", "projectPath", "color", "icon", "requestId"]);
|
|
@@ -36686,6 +36715,11 @@ var require_mobile_runtime = __commonJS({
|
|
|
36686
36715
|
exactPayload(["rootId"]);
|
|
36687
36716
|
return this.gitAvailability({ rootId: cleanText(payload.rootId, 128) });
|
|
36688
36717
|
}
|
|
36718
|
+
if (command.type === "project.github.repositories") {
|
|
36719
|
+
exactPayload(["rootId"]);
|
|
36720
|
+
if (typeof this.listGitHubRepositories !== "function") throw new Error("Remote GitHub import is unavailable");
|
|
36721
|
+
return this.listGitHubRepositories();
|
|
36722
|
+
}
|
|
36689
36723
|
if (command.type === "project.icon.availability") {
|
|
36690
36724
|
if (typeof this.projectIconAvailability !== "function") return { available: false };
|
|
36691
36725
|
exactPayload(["projectId"]);
|
|
@@ -36709,11 +36743,12 @@ var require_mobile_runtime = __commonJS({
|
|
|
36709
36743
|
}
|
|
36710
36744
|
if (command.type === "project.clone") {
|
|
36711
36745
|
if (typeof this.cloneProject !== "function") throw new Error("Remote project cloning is unavailable");
|
|
36712
|
-
exactPayload(["rootId", "url", "relativePath", "displayName", "color", "icon", "requestId"]);
|
|
36746
|
+
exactPayload(["rootId", "url", "relativePath", "displayName", "color", "icon", "requestId", "githubRepository"]);
|
|
36713
36747
|
if (typeof payload.requestId !== "string" || !payload.requestId) throw new Error("A clone requestId is required");
|
|
36714
36748
|
return this.cloneProject({
|
|
36715
36749
|
rootId: payload.rootId,
|
|
36716
36750
|
url: payload.url,
|
|
36751
|
+
...payload.githubRepository !== void 0 ? { githubRepository: payload.githubRepository } : {},
|
|
36717
36752
|
relativePath: payload.relativePath,
|
|
36718
36753
|
displayName: payload.displayName,
|
|
36719
36754
|
color: payload.color,
|
|
@@ -38731,6 +38766,9 @@ var require_remote_runtime_client = __commonJS({
|
|
|
38731
38766
|
"project.clone",
|
|
38732
38767
|
"project.clone.cancel",
|
|
38733
38768
|
"project.git.availability",
|
|
38769
|
+
"project.github.repositories",
|
|
38770
|
+
"project.locations.list",
|
|
38771
|
+
"project.locations.add",
|
|
38734
38772
|
"project.icon.availability",
|
|
38735
38773
|
"project.icon.generate",
|
|
38736
38774
|
"project.unregister",
|
|
@@ -41539,6 +41577,107 @@ var require_headless_chat_preferences = __commonJS({
|
|
|
41539
41577
|
}
|
|
41540
41578
|
});
|
|
41541
41579
|
|
|
41580
|
+
// src/infrastructure/services/remote-project-locations.js
|
|
41581
|
+
var require_remote_project_locations = __commonJS({
|
|
41582
|
+
"src/infrastructure/services/remote-project-locations.js"(exports2, module2) {
|
|
41583
|
+
"use strict";
|
|
41584
|
+
var crypto = require("crypto");
|
|
41585
|
+
var fs = require("fs");
|
|
41586
|
+
var os = require("os");
|
|
41587
|
+
var path = require("path");
|
|
41588
|
+
function locationError(code, message) {
|
|
41589
|
+
return Object.assign(new Error(message), { code });
|
|
41590
|
+
}
|
|
41591
|
+
var RemoteProjectLocations = class {
|
|
41592
|
+
constructor() {
|
|
41593
|
+
this.locations = /* @__PURE__ */ new Map();
|
|
41594
|
+
}
|
|
41595
|
+
remember(candidate) {
|
|
41596
|
+
var _a;
|
|
41597
|
+
const resolved = fs.realpathSync(candidate);
|
|
41598
|
+
const stat = fs.statSync(resolved);
|
|
41599
|
+
if (!stat.isDirectory()) throw new Error("Choose an existing folder");
|
|
41600
|
+
let locationId = (_a = [...this.locations].find(([, entry]) => entry.path === resolved)) == null ? void 0 : _a[0];
|
|
41601
|
+
const previous = this.locations.get(locationId);
|
|
41602
|
+
if (previous && (previous.dev !== stat.dev || previous.ino !== stat.ino)) {
|
|
41603
|
+
this.locations.delete(locationId);
|
|
41604
|
+
locationId = null;
|
|
41605
|
+
}
|
|
41606
|
+
if (!locationId) {
|
|
41607
|
+
if (this.locations.size >= 4096) this.locations.delete(this.locations.keys().next().value);
|
|
41608
|
+
locationId = crypto.randomBytes(18).toString("base64url");
|
|
41609
|
+
this.locations.set(locationId, { path: resolved, dev: stat.dev, ino: stat.ino });
|
|
41610
|
+
}
|
|
41611
|
+
return { locationId, name: path.basename(resolved) || path.parse(resolved).root };
|
|
41612
|
+
}
|
|
41613
|
+
resolve(locationId) {
|
|
41614
|
+
const entry = this.locations.get(locationId);
|
|
41615
|
+
if (!entry) throw locationError("location_expired", "This folder selection expired. Browse again.");
|
|
41616
|
+
try {
|
|
41617
|
+
const stat = fs.lstatSync(entry.path);
|
|
41618
|
+
if (!stat.isDirectory() || fs.realpathSync(entry.path) !== entry.path || stat.dev !== entry.dev || stat.ino !== entry.ino) throw new Error();
|
|
41619
|
+
} catch (_) {
|
|
41620
|
+
throw locationError("location_expired", "The folder changed. Browse again.");
|
|
41621
|
+
}
|
|
41622
|
+
return entry.path;
|
|
41623
|
+
}
|
|
41624
|
+
writable(locationId) {
|
|
41625
|
+
const resolved = this.resolve(locationId);
|
|
41626
|
+
const stat = fs.statSync(resolved);
|
|
41627
|
+
const uid = typeof process.geteuid === "function" ? process.geteuid() : null;
|
|
41628
|
+
if (resolved === path.parse(resolved).root || uid !== null && (stat.uid !== uid || (stat.mode & 18) !== 0)) {
|
|
41629
|
+
throw locationError("location_permission_denied", "Choose a private folder owned by the remote service user, not a whole drive.");
|
|
41630
|
+
}
|
|
41631
|
+
try {
|
|
41632
|
+
fs.accessSync(resolved, fs.constants.R_OK | fs.constants.W_OK | fs.constants.X_OK);
|
|
41633
|
+
} catch (_) {
|
|
41634
|
+
throw locationError("location_permission_denied", "The remote service cannot read and write this folder. Choose another location.");
|
|
41635
|
+
}
|
|
41636
|
+
return resolved;
|
|
41637
|
+
}
|
|
41638
|
+
list({ locationId, offset = 0 } = {}, roots = []) {
|
|
41639
|
+
var _a;
|
|
41640
|
+
if (!Number.isSafeInteger(offset) || offset < 0 || offset > 1e5) throw new Error("Invalid folder page");
|
|
41641
|
+
const shortcuts = [os.homedir(), ...roots];
|
|
41642
|
+
if (process.platform === "win32") {
|
|
41643
|
+
for (const letter of "ABCDEFGHIJKLMNOPQRSTUVWXYZ") if (fs.existsSync(`${letter}:\\`)) shortcuts.push(`${letter}:\\`);
|
|
41644
|
+
} else shortcuts.push("/");
|
|
41645
|
+
const locations = [...new Set(shortcuts)].flatMap((candidate) => {
|
|
41646
|
+
try {
|
|
41647
|
+
return [this.remember(candidate)];
|
|
41648
|
+
} catch (_) {
|
|
41649
|
+
return [];
|
|
41650
|
+
}
|
|
41651
|
+
});
|
|
41652
|
+
const current = locationId ? this.resolve(locationId) : this.resolve((_a = locations[0]) == null ? void 0 : _a.locationId);
|
|
41653
|
+
let entries;
|
|
41654
|
+
try {
|
|
41655
|
+
entries = fs.readdirSync(current, { withFileTypes: true });
|
|
41656
|
+
} catch (_) {
|
|
41657
|
+
throw locationError("location_permission_denied", "The remote service cannot read this folder. Choose another location.");
|
|
41658
|
+
}
|
|
41659
|
+
const folders = entries.filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).sort((left, right) => left.name.localeCompare(right.name, void 0, { numeric: true }));
|
|
41660
|
+
const directories = folders.slice(offset, offset + 200).flatMap((entry) => {
|
|
41661
|
+
try {
|
|
41662
|
+
return [this.remember(path.join(current, entry.name))];
|
|
41663
|
+
} catch (_) {
|
|
41664
|
+
return [];
|
|
41665
|
+
}
|
|
41666
|
+
});
|
|
41667
|
+
const parent = path.dirname(current);
|
|
41668
|
+
return {
|
|
41669
|
+
...this.remember(current),
|
|
41670
|
+
parentLocationId: parent === current ? null : this.remember(parent).locationId,
|
|
41671
|
+
locations,
|
|
41672
|
+
directories,
|
|
41673
|
+
nextOffset: offset + 200 < folders.length ? offset + 200 : null
|
|
41674
|
+
};
|
|
41675
|
+
}
|
|
41676
|
+
};
|
|
41677
|
+
module2.exports = { RemoteProjectLocations };
|
|
41678
|
+
}
|
|
41679
|
+
});
|
|
41680
|
+
|
|
41542
41681
|
// src/infrastructure/headless/headless-project-registry.js
|
|
41543
41682
|
var require_headless_project_registry = __commonJS({
|
|
41544
41683
|
"src/infrastructure/headless/headless-project-registry.js"(exports2, module2) {
|
|
@@ -41546,6 +41685,7 @@ var require_headless_project_registry = __commonJS({
|
|
|
41546
41685
|
var fs = require("fs");
|
|
41547
41686
|
var path = require("path");
|
|
41548
41687
|
var { spawn } = require("child_process");
|
|
41688
|
+
var { RemoteProjectLocations } = require_remote_project_locations();
|
|
41549
41689
|
var ID_PATTERN = /^[A-Za-z0-9_-]{16,128}$/;
|
|
41550
41690
|
var MAX_CLONES = 2;
|
|
41551
41691
|
var MAX_QUEUE = 20;
|
|
@@ -41639,6 +41779,7 @@ var require_headless_project_registry = __commonJS({
|
|
|
41639
41779
|
this.database = database;
|
|
41640
41780
|
this.db = database.db;
|
|
41641
41781
|
this.runtimeId = runtimeId;
|
|
41782
|
+
this.locations = new RemoteProjectLocations();
|
|
41642
41783
|
this.spawnImpl = spawnImpl;
|
|
41643
41784
|
this.onProjectsChanged = onProjectsChanged;
|
|
41644
41785
|
this.onOperation = onOperation;
|
|
@@ -41884,6 +42025,20 @@ var require_headless_project_registry = __commonJS({
|
|
|
41884
42025
|
getRoots() {
|
|
41885
42026
|
return this.db.prepare("SELECT root_id, name FROM runtime_project_roots ORDER BY created_at, root_id").all().map((root) => ({ rootId: root.root_id, name: String(root.name).slice(0, 200) }));
|
|
41886
42027
|
}
|
|
42028
|
+
listLocations(payload) {
|
|
42029
|
+
return this.locations.list(payload, this.db.prepare("SELECT path FROM runtime_project_roots").all().map((root) => root.path));
|
|
42030
|
+
}
|
|
42031
|
+
addLocation({ locationId }) {
|
|
42032
|
+
const resolved = this.locations.writable(locationId);
|
|
42033
|
+
const existing = this.db.prepare("SELECT root_id FROM runtime_project_roots WHERE path = ?").get(resolved);
|
|
42034
|
+
if (existing) return { rootId: existing.root_id, name: path.basename(resolved) };
|
|
42035
|
+
if (this.getRoots().length >= 100) throw new Error("At most 100 project locations can be saved");
|
|
42036
|
+
const rootId = randomId();
|
|
42037
|
+
const name = path.basename(resolved);
|
|
42038
|
+
this.db.prepare("INSERT INTO runtime_project_roots (root_id, path, name) VALUES (?, ?, ?)").run(rootId, resolved, name);
|
|
42039
|
+
this._bumpRevision();
|
|
42040
|
+
return { rootId, name };
|
|
42041
|
+
}
|
|
41887
42042
|
gitAvailability() {
|
|
41888
42043
|
return new Promise((resolve) => {
|
|
41889
42044
|
var _a, _b;
|
|
@@ -42083,7 +42238,7 @@ var require_headless_project_registry = __commonJS({
|
|
|
42083
42238
|
const revision = this._bumpRevision();
|
|
42084
42239
|
return this._recordRequest(requestId, hash, { projectId: project.projectId, revision, updated: true });
|
|
42085
42240
|
}
|
|
42086
|
-
clone({ rootId, url, relativePath, displayName, color, icon, requestId }) {
|
|
42241
|
+
clone({ rootId, url, relativePath, displayName, color, icon, requestId, gitConfig = [] }) {
|
|
42087
42242
|
const normalizedUrl = validateGitUrl(url);
|
|
42088
42243
|
const root = this._root(rootId);
|
|
42089
42244
|
this._assertSecureCloneRoot(root);
|
|
@@ -42096,7 +42251,7 @@ var require_headless_project_registry = __commonJS({
|
|
|
42096
42251
|
if (appearance.displayName !== void 0 && !appearance.displayName || appearance.icon !== void 0 && appearance.icon !== null && (typeof appearance.icon !== "string" || !ICON_PATTERN.test(appearance.icon))) {
|
|
42097
42252
|
throw runtimeError("invalid_project_update", "Project changes are invalid");
|
|
42098
42253
|
}
|
|
42099
|
-
const hash = requestHash("clone", { rootId, url: normalizedUrl, relativePath: normalizedRelative, ...appearance });
|
|
42254
|
+
const hash = requestHash("clone", { rootId, url: normalizedUrl, relativePath: normalizedRelative, ...appearance, ...gitConfig.length ? { gitConfig } : {} });
|
|
42100
42255
|
const duplicate = this._request(requestId, hash);
|
|
42101
42256
|
if (duplicate) return duplicate;
|
|
42102
42257
|
const destinationInfo = this._cloneDestination(root, normalizedRelative, normalizedUrl);
|
|
@@ -42113,6 +42268,7 @@ var require_headless_project_registry = __commonJS({
|
|
|
42113
42268
|
requestId,
|
|
42114
42269
|
rootId,
|
|
42115
42270
|
url: normalizedUrl,
|
|
42271
|
+
gitConfig,
|
|
42116
42272
|
appearance,
|
|
42117
42273
|
destination: destinationInfo.destination,
|
|
42118
42274
|
temporaryDestination: null,
|
|
@@ -42212,7 +42368,7 @@ var require_headless_project_registry = __commonJS({
|
|
|
42212
42368
|
this._emitOperation(operation.operationId, operation.requestId, "running");
|
|
42213
42369
|
let child;
|
|
42214
42370
|
try {
|
|
42215
|
-
child = this.spawnImpl("git", ["-c", "protocol.file.allow=never", "clone", "--", operation.url, operation.temporaryDestination], {
|
|
42371
|
+
child = this.spawnImpl("git", ["-c", "protocol.file.allow=never", ...operation.gitConfig, "clone", "--", operation.url, operation.temporaryDestination], {
|
|
42216
42372
|
shell: false,
|
|
42217
42373
|
stdio: ["ignore", "pipe", "pipe"],
|
|
42218
42374
|
env: { ...process.env, GIT_TERMINAL_PROMPT: "0", GIT_ALLOW_PROTOCOL: "https:ssh" }
|
|
@@ -42350,6 +42506,272 @@ var require_headless_project_registry = __commonJS({
|
|
|
42350
42506
|
}
|
|
42351
42507
|
});
|
|
42352
42508
|
|
|
42509
|
+
// src/shared/utils/executable-candidate.js
|
|
42510
|
+
var require_executable_candidate = __commonJS({
|
|
42511
|
+
"src/shared/utils/executable-candidate.js"(exports2, module2) {
|
|
42512
|
+
var fs = require("fs");
|
|
42513
|
+
var WINDOWS_EXECUTABLE_EXTENSIONS = [".exe", ".cmd", ".bat"];
|
|
42514
|
+
function candidateVariants(candidate, platform = process.platform) {
|
|
42515
|
+
const value = String(candidate || "").trim();
|
|
42516
|
+
if (!value) return [];
|
|
42517
|
+
if (platform !== "win32" || /\.(exe|cmd|bat)$/i.test(value)) return [value];
|
|
42518
|
+
return WINDOWS_EXECUTABLE_EXTENSIONS.map((extension) => `${value}${extension}`);
|
|
42519
|
+
}
|
|
42520
|
+
function isRunnableExecutableCandidate(candidate, {
|
|
42521
|
+
fsImpl = fs,
|
|
42522
|
+
platform = process.platform
|
|
42523
|
+
} = {}) {
|
|
42524
|
+
const value = String(candidate || "").trim();
|
|
42525
|
+
if (!value) return false;
|
|
42526
|
+
if (platform === "win32" && !/\.(exe|cmd|bat)$/i.test(value)) return false;
|
|
42527
|
+
try {
|
|
42528
|
+
const stats = fsImpl.statSync(value);
|
|
42529
|
+
if (!stats.isFile() || stats.size <= 0) return false;
|
|
42530
|
+
if (platform !== "win32") fsImpl.accessSync(value, fs.constants.X_OK);
|
|
42531
|
+
return true;
|
|
42532
|
+
} catch (_) {
|
|
42533
|
+
return false;
|
|
42534
|
+
}
|
|
42535
|
+
}
|
|
42536
|
+
function findRunnableExecutableCandidate(candidates, options = {}) {
|
|
42537
|
+
const platform = options.platform || process.platform;
|
|
42538
|
+
for (const candidate of candidates || []) {
|
|
42539
|
+
for (const variant of candidateVariants(candidate, platform)) {
|
|
42540
|
+
if (isRunnableExecutableCandidate(variant, { ...options, platform })) return variant;
|
|
42541
|
+
}
|
|
42542
|
+
}
|
|
42543
|
+
return null;
|
|
42544
|
+
}
|
|
42545
|
+
module2.exports = {
|
|
42546
|
+
candidateVariants,
|
|
42547
|
+
findRunnableExecutableCandidate,
|
|
42548
|
+
isRunnableExecutableCandidate
|
|
42549
|
+
};
|
|
42550
|
+
}
|
|
42551
|
+
});
|
|
42552
|
+
|
|
42553
|
+
// src/infrastructure/services/github-project-import-service.js
|
|
42554
|
+
var require_github_project_import_service = __commonJS({
|
|
42555
|
+
"src/infrastructure/services/github-project-import-service.js"(exports2, module2) {
|
|
42556
|
+
"use strict";
|
|
42557
|
+
var fs = require("fs");
|
|
42558
|
+
var os = require("os");
|
|
42559
|
+
var path = require("path");
|
|
42560
|
+
var { execFile } = require("child_process");
|
|
42561
|
+
var { findRunnableExecutableCandidate } = require_executable_candidate();
|
|
42562
|
+
var REPOSITORY_PATTERN = /^[A-Za-z0-9](?:[A-Za-z0-9-]{0,38})\/[A-Za-z0-9._-]+$/;
|
|
42563
|
+
var GitHubProjectImportService = class {
|
|
42564
|
+
constructor({
|
|
42565
|
+
execFileImpl = execFile,
|
|
42566
|
+
fsImpl = fs,
|
|
42567
|
+
osImpl = os,
|
|
42568
|
+
pathImpl = path,
|
|
42569
|
+
resolveEnv = async () => ({}),
|
|
42570
|
+
resolveExecutable = null
|
|
42571
|
+
} = {}) {
|
|
42572
|
+
this.execFile = execFileImpl;
|
|
42573
|
+
this.fs = fsImpl;
|
|
42574
|
+
this.os = osImpl;
|
|
42575
|
+
this.path = pathImpl;
|
|
42576
|
+
this.resolveEnv = resolveEnv;
|
|
42577
|
+
this.resolveExecutable = resolveExecutable;
|
|
42578
|
+
this.executablePath = null;
|
|
42579
|
+
}
|
|
42580
|
+
async _env() {
|
|
42581
|
+
const resolved = await this.resolveEnv();
|
|
42582
|
+
const env = { ...process.env };
|
|
42583
|
+
for (const [key, value] of Object.entries(resolved || {})) {
|
|
42584
|
+
for (const existingKey of Object.keys(env)) {
|
|
42585
|
+
if (existingKey !== key && existingKey.toUpperCase() === key.toUpperCase()) delete env[existingKey];
|
|
42586
|
+
}
|
|
42587
|
+
env[key] = value;
|
|
42588
|
+
}
|
|
42589
|
+
return env;
|
|
42590
|
+
}
|
|
42591
|
+
async _findExecutable(env) {
|
|
42592
|
+
if (this.executablePath) return this.executablePath;
|
|
42593
|
+
if (this.resolveExecutable) {
|
|
42594
|
+
this.executablePath = await this.resolveExecutable(env);
|
|
42595
|
+
return this.executablePath;
|
|
42596
|
+
}
|
|
42597
|
+
const pathValue = env.PATH || env.Path || "";
|
|
42598
|
+
const candidates = pathValue.split(this.path.delimiter).filter(Boolean).map((directory) => this.path.join(directory, "gh"));
|
|
42599
|
+
if (process.platform === "win32") {
|
|
42600
|
+
candidates.push("C:\\Program Files\\GitHub CLI\\gh.exe");
|
|
42601
|
+
}
|
|
42602
|
+
this.executablePath = findRunnableExecutableCandidate(candidates);
|
|
42603
|
+
return this.executablePath;
|
|
42604
|
+
}
|
|
42605
|
+
async _run(args, { timeout = 3e4, maxBuffer = 20 * 1024 * 1024 } = {}) {
|
|
42606
|
+
const env = await this._env();
|
|
42607
|
+
const executable = await this._findExecutable(env);
|
|
42608
|
+
if (!executable) {
|
|
42609
|
+
const error = new Error("GitHub CLI is not installed");
|
|
42610
|
+
error.code = "github_cli_missing";
|
|
42611
|
+
throw error;
|
|
42612
|
+
}
|
|
42613
|
+
return new Promise((resolve, reject) => {
|
|
42614
|
+
this.execFile(executable, args, { env, timeout, maxBuffer, windowsHide: true }, (error, stdout = "", stderr = "") => {
|
|
42615
|
+
if (error) {
|
|
42616
|
+
error.stdout = stdout;
|
|
42617
|
+
error.stderr = stderr;
|
|
42618
|
+
reject(error);
|
|
42619
|
+
return;
|
|
42620
|
+
}
|
|
42621
|
+
resolve({ stdout, stderr });
|
|
42622
|
+
});
|
|
42623
|
+
});
|
|
42624
|
+
}
|
|
42625
|
+
_defaultBaseDirectory() {
|
|
42626
|
+
const home = this.os.homedir();
|
|
42627
|
+
for (const candidate of [this.path.join(home, "Development"), this.path.join(home, "Developer"), home]) {
|
|
42628
|
+
try {
|
|
42629
|
+
if (this.fs.statSync(candidate).isDirectory()) return candidate;
|
|
42630
|
+
} catch (_) {
|
|
42631
|
+
}
|
|
42632
|
+
}
|
|
42633
|
+
return home;
|
|
42634
|
+
}
|
|
42635
|
+
_message(error) {
|
|
42636
|
+
return String((error == null ? void 0 : error.stderr) || (error == null ? void 0 : error.message) || "GitHub request failed").replace(/\x1B\[[0-?]*[ -/]*[@-~]/g, "").replace(/\s+/g, " ").trim().slice(0, 500);
|
|
42637
|
+
}
|
|
42638
|
+
async getStatus() {
|
|
42639
|
+
const env = await this._env();
|
|
42640
|
+
const executable = await this._findExecutable(env);
|
|
42641
|
+
const base = { defaultBaseDirectory: this._defaultBaseDirectory() };
|
|
42642
|
+
if (!executable) return { success: true, installed: false, authenticated: false, ...base };
|
|
42643
|
+
try {
|
|
42644
|
+
const { stdout } = await this._run(["api", "user"]);
|
|
42645
|
+
const user = JSON.parse(stdout);
|
|
42646
|
+
return {
|
|
42647
|
+
success: true,
|
|
42648
|
+
installed: true,
|
|
42649
|
+
authenticated: true,
|
|
42650
|
+
account: {
|
|
42651
|
+
login: user.login,
|
|
42652
|
+
name: user.name || user.login,
|
|
42653
|
+
avatarUrl: user.avatar_url || null
|
|
42654
|
+
},
|
|
42655
|
+
...base
|
|
42656
|
+
};
|
|
42657
|
+
} catch (error) {
|
|
42658
|
+
return { success: true, installed: true, authenticated: false, error: this._message(error), ...base };
|
|
42659
|
+
}
|
|
42660
|
+
}
|
|
42661
|
+
async listRepositories() {
|
|
42662
|
+
try {
|
|
42663
|
+
const { stdout } = await this._run([
|
|
42664
|
+
"api",
|
|
42665
|
+
"--paginate",
|
|
42666
|
+
"--slurp",
|
|
42667
|
+
"user/repos?per_page=100&sort=updated&affiliation=owner,collaborator,organization_member"
|
|
42668
|
+
]);
|
|
42669
|
+
const parsed = JSON.parse(stdout);
|
|
42670
|
+
const repositories = (Array.isArray(parsed[0]) ? parsed.flat() : parsed).filter((repo) => repo && repo.full_name && repo.name).map((repo) => {
|
|
42671
|
+
var _a;
|
|
42672
|
+
return {
|
|
42673
|
+
id: repo.id,
|
|
42674
|
+
name: repo.name,
|
|
42675
|
+
fullName: repo.full_name,
|
|
42676
|
+
description: repo.description || "",
|
|
42677
|
+
isPrivate: Boolean(repo.private),
|
|
42678
|
+
isFork: Boolean(repo.fork),
|
|
42679
|
+
updatedAt: repo.updated_at || null,
|
|
42680
|
+
language: repo.language || null,
|
|
42681
|
+
owner: ((_a = repo.owner) == null ? void 0 : _a.login) || repo.full_name.split("/")[0],
|
|
42682
|
+
url: repo.html_url || `https://github.com/${repo.full_name}`
|
|
42683
|
+
};
|
|
42684
|
+
});
|
|
42685
|
+
return { success: true, repositories };
|
|
42686
|
+
} catch (error) {
|
|
42687
|
+
return { success: false, error: this._message(error), code: error.code || "github_request_failed" };
|
|
42688
|
+
}
|
|
42689
|
+
}
|
|
42690
|
+
async connect() {
|
|
42691
|
+
try {
|
|
42692
|
+
await this._run(
|
|
42693
|
+
["auth", "login", "--hostname", "github.com", "--git-protocol", "https", "--web"],
|
|
42694
|
+
{ timeout: 10 * 6e4, maxBuffer: 1024 * 1024 }
|
|
42695
|
+
);
|
|
42696
|
+
return this.getStatus();
|
|
42697
|
+
} catch (error) {
|
|
42698
|
+
return { success: false, error: this._message(error), code: error.code || "github_auth_failed" };
|
|
42699
|
+
}
|
|
42700
|
+
}
|
|
42701
|
+
async remoteRepositories() {
|
|
42702
|
+
var _a;
|
|
42703
|
+
const status = await this.getStatus();
|
|
42704
|
+
const result = { success: true, installed: status.installed, authenticated: status.authenticated };
|
|
42705
|
+
if (!status.authenticated) return result;
|
|
42706
|
+
const listed = await this.listRepositories();
|
|
42707
|
+
if (!listed.success) return { success: false, error: "Could not load repositories from GitHub on the remote computer." };
|
|
42708
|
+
return {
|
|
42709
|
+
...result,
|
|
42710
|
+
account: { login: String(((_a = status.account) == null ? void 0 : _a.login) || "").slice(0, 100) },
|
|
42711
|
+
repositories: listed.repositories.filter((repo) => typeof repo.fullName === "string" && repo.fullName.length <= 240 && REPOSITORY_PATTERN.test(repo.fullName)).slice(0, 500).map((repo) => ({
|
|
42712
|
+
name: repo.fullName.split("/")[1],
|
|
42713
|
+
fullName: repo.fullName,
|
|
42714
|
+
owner: repo.fullName.split("/")[0],
|
|
42715
|
+
description: String(repo.description || "").slice(0, 300),
|
|
42716
|
+
language: String(repo.language || "").slice(0, 80),
|
|
42717
|
+
isPrivate: repo.isPrivate === true
|
|
42718
|
+
})),
|
|
42719
|
+
truncated: listed.repositories.length > 500
|
|
42720
|
+
};
|
|
42721
|
+
}
|
|
42722
|
+
async prepareRemoteClone(payload) {
|
|
42723
|
+
if (payload.githubRepository === void 0) return payload;
|
|
42724
|
+
const repository = payload.githubRepository;
|
|
42725
|
+
if (typeof repository !== "string" || repository.length > 240 || !REPOSITORY_PATTERN.test(repository) || payload.url !== `https://github.com/${repository}.git`) {
|
|
42726
|
+
throw Object.assign(new Error("Choose a valid GitHub repository"), { code: "invalid_git_url" });
|
|
42727
|
+
}
|
|
42728
|
+
const executable = await this._findExecutable(await this._env());
|
|
42729
|
+
if (!executable) throw Object.assign(new Error("GitHub CLI is not installed on this computer"), { code: "github_cli_missing" });
|
|
42730
|
+
const quoted = `'${executable.replace(/\\/g, "/").replace(/'/g, `'\\''`)}'`;
|
|
42731
|
+
return {
|
|
42732
|
+
...payload,
|
|
42733
|
+
gitConfig: ["-c", "credential.helper=", "-c", `credential.https://github.com.helper=!${quoted} auth git-credential`]
|
|
42734
|
+
};
|
|
42735
|
+
}
|
|
42736
|
+
async cloneRepository({ repository, baseDirectory }) {
|
|
42737
|
+
const fullName = String(repository || "").trim();
|
|
42738
|
+
const rawBase = String(baseDirectory || "").trim();
|
|
42739
|
+
if (!REPOSITORY_PATTERN.test(fullName)) {
|
|
42740
|
+
return { success: false, code: "invalid_repository", error: "Invalid GitHub repository" };
|
|
42741
|
+
}
|
|
42742
|
+
if (!rawBase || !this.path.isAbsolute(rawBase)) {
|
|
42743
|
+
return { success: false, code: "invalid_destination", error: "Choose an absolute destination directory" };
|
|
42744
|
+
}
|
|
42745
|
+
const base = this.path.resolve(rawBase);
|
|
42746
|
+
try {
|
|
42747
|
+
const stats = await this.fs.promises.stat(base);
|
|
42748
|
+
if (!stats.isDirectory()) throw new Error("Destination is not a directory");
|
|
42749
|
+
await this.fs.promises.access(base, this.fs.constants.W_OK);
|
|
42750
|
+
} catch (error) {
|
|
42751
|
+
return { success: false, code: "invalid_destination", error: this._message(error) };
|
|
42752
|
+
}
|
|
42753
|
+
const name = fullName.split("/")[1];
|
|
42754
|
+
const destination = this.path.resolve(base, name);
|
|
42755
|
+
if (this.path.dirname(destination) !== base) {
|
|
42756
|
+
return { success: false, code: "invalid_destination", error: "Invalid destination directory" };
|
|
42757
|
+
}
|
|
42758
|
+
if (this.fs.existsSync(destination)) {
|
|
42759
|
+
return { success: false, code: "destination_exists", error: "The destination folder already exists", path: destination };
|
|
42760
|
+
}
|
|
42761
|
+
try {
|
|
42762
|
+
await this._run(["repo", "clone", fullName, destination], { timeout: 30 * 6e4 });
|
|
42763
|
+
const stats = await this.fs.promises.stat(destination);
|
|
42764
|
+
if (!stats.isDirectory()) throw new Error("GitHub CLI did not create the repository directory");
|
|
42765
|
+
return { success: true, path: destination, repository: fullName };
|
|
42766
|
+
} catch (error) {
|
|
42767
|
+
return { success: false, code: error.code || "clone_failed", error: this._message(error) };
|
|
42768
|
+
}
|
|
42769
|
+
}
|
|
42770
|
+
};
|
|
42771
|
+
module2.exports = { GitHubProjectImportService, REPOSITORY_PATTERN };
|
|
42772
|
+
}
|
|
42773
|
+
});
|
|
42774
|
+
|
|
42353
42775
|
// src/infrastructure/headless/headless-task-service.js
|
|
42354
42776
|
var require_headless_task_service = __commonJS({
|
|
42355
42777
|
"src/infrastructure/headless/headless-task-service.js"(exports2, module2) {
|
|
@@ -45486,7 +45908,7 @@ var require_database = __commonJS({
|
|
|
45486
45908
|
{ status_key: "needs_testing", label: "Needs testing", color: "#3b82f6", icon: "flask-conical", sort_order: 2, is_default: 1, agent_settable: 1, prompt: "Set it when you finish the implementation and the work is pending the user testing it manually. Do not set it if there are still things left to implement." },
|
|
45487
45909
|
{ status_key: "working", label: "Working", color: "#fbbf24", icon: "hammer", sort_order: 3, is_default: 1, agent_settable: 1, prompt: "Set it when you start working on any request and while you are implementing, investigating or fixing something." },
|
|
45488
45910
|
{ status_key: "done", label: "Done", color: "#22c55e", icon: "circle-check", sort_order: 4, is_default: 1, agent_settable: 1, prompt: "Set it when the work is completely finished: implemented, validated and with its commit/push done when applicable. It is the final state." },
|
|
45489
|
-
{ status_key: "idle", label: "Idle", color: "#6b7280", icon: "circle-dashed", sort_order: 5, is_default: 1, agent_settable: 0, prompt: "Set by the app
|
|
45911
|
+
{ status_key: "idle", label: "Idle", color: "#6b7280", icon: "circle-dashed", sort_order: 5, is_default: 1, agent_settable: 0, prompt: "Set by the app on an agent that has just been opened and has not been given any work yet. Agents cannot set this status; it clears itself as soon as you send the agent something." }
|
|
45490
45912
|
];
|
|
45491
45913
|
var IDLE_TERMINAL_STATUS_KEY = "idle";
|
|
45492
45914
|
var IDLE_STATUS_SEEDED_SETTING = "terminal_status_idle_seeded";
|
|
@@ -45499,7 +45921,7 @@ var require_database = __commonJS({
|
|
|
45499
45921
|
done: 6
|
|
45500
45922
|
};
|
|
45501
45923
|
var LEGACY_DEFAULT_PROMPTS = {
|
|
45502
|
-
idle: "Set by the app
|
|
45924
|
+
idle: "Set by the app when an agent is resting without an explicit work status, including after a reply finishes. It does not mean the work is complete or that user input is required. Agents cannot set this status.",
|
|
45503
45925
|
working: "Ponlo al empezar a trabajar en cualquier petici\xF3n y mientras est\xE9s implementando, investigando o arreglando algo.",
|
|
45504
45926
|
needs_input: "Ponlo cuando pares porque necesites una respuesta o decisi\xF3n del usuario para continuar (una pregunta, una elecci\xF3n de dise\xF1o, un permiso).",
|
|
45505
45927
|
needs_testing: "Ponlo cuando termines la implementaci\xF3n y el trabajo quede pendiente de que el usuario lo pruebe a mano. No lo pongas si a\xFAn quedan cosas por implementar.",
|
|
@@ -49548,6 +49970,7 @@ var require_headless_runtime = __commonJS({
|
|
|
49548
49970
|
var { HeadlessSessionBridge } = require_headless_session_bridge();
|
|
49549
49971
|
var { createHeadlessChatPreferences } = require_headless_chat_preferences();
|
|
49550
49972
|
var { HeadlessProjectRegistry } = require_headless_project_registry();
|
|
49973
|
+
var { GitHubProjectImportService } = require_github_project_import_service();
|
|
49551
49974
|
var { AGENT_IDS, HeadlessProviderService } = require_headless_provider_service();
|
|
49552
49975
|
var { HeadlessTaskService } = require_headless_task_service();
|
|
49553
49976
|
var {
|
|
@@ -49582,11 +50005,14 @@ var require_headless_runtime = __commonJS({
|
|
|
49582
50005
|
var HEADLESS_PROJECT_CAPABILITIES = Object.freeze([
|
|
49583
50006
|
"projects.list",
|
|
49584
50007
|
"project.directories.list",
|
|
50008
|
+
"project.locations.list",
|
|
50009
|
+
"project.locations.add",
|
|
49585
50010
|
"project.update",
|
|
49586
50011
|
"project.register",
|
|
49587
50012
|
"project.clone",
|
|
49588
50013
|
"project.clone.cancel",
|
|
49589
50014
|
"project.git.availability",
|
|
50015
|
+
"project.github.repositories",
|
|
49590
50016
|
"project.unregister",
|
|
49591
50017
|
"shortcuts.manage",
|
|
49592
50018
|
"session.action",
|
|
@@ -50354,9 +50780,12 @@ ${message}`;
|
|
|
50354
50780
|
workspaceGitCreate: inProject(workspace.gitCreate),
|
|
50355
50781
|
listProjects: (payload) => registry.list(payload),
|
|
50356
50782
|
listProjectDirectories: (payload) => registry.listDirectories(payload),
|
|
50783
|
+
listProjectLocations: (payload) => registry.listLocations(payload),
|
|
50784
|
+
addProjectLocation: (payload) => registry.addLocation(payload),
|
|
50357
50785
|
updateProject: (payload) => registry.update(payload),
|
|
50358
50786
|
registerProject: (payload) => registry.register(payload),
|
|
50359
|
-
cloneProject: (payload) => registry.clone(payload),
|
|
50787
|
+
cloneProject: async (payload) => registry.clone(await new GitHubProjectImportService().prepareRemoteClone(payload)),
|
|
50788
|
+
listGitHubRepositories: () => new GitHubProjectImportService().remoteRepositories(),
|
|
50360
50789
|
cancelProjectClone: (payload) => registry.cancelClone(payload),
|
|
50361
50790
|
gitAvailability: () => registry.gitAvailability(),
|
|
50362
50791
|
unregisterProject: (payload) => {
|
|
@@ -51043,7 +51472,7 @@ var require_cas = __commonJS({
|
|
|
51043
51472
|
loadIdentity,
|
|
51044
51473
|
resolveProject
|
|
51045
51474
|
} = require_headless_runtime();
|
|
51046
|
-
var version = true ? "0.0.
|
|
51475
|
+
var version = true ? "0.0.18" : JSON.parse(fs.readFileSync(path.join(__dirname, "..", "..", "package.json"), "utf8")).version;
|
|
51047
51476
|
function help() {
|
|
51048
51477
|
return `CAS CLI ${version}
|
|
51049
51478
|
|
package/dist/mcp-stdio-server.js
CHANGED
|
@@ -1068,7 +1068,7 @@ var require_database_mcp_standalone = __commonJS({
|
|
|
1068
1068
|
{ status_key: "needs_testing", label: "Needs testing", color: "#3b82f6", icon: "flask-conical", sort_order: 2, is_default: 1, agent_settable: 1, prompt: "Set it when you finish the implementation and the work is pending the user testing it manually. Do not set it if there are still things left to implement." },
|
|
1069
1069
|
{ status_key: "working", label: "Working", color: "#fbbf24", icon: "hammer", sort_order: 3, is_default: 1, agent_settable: 1, prompt: "Set it when you start working on any request and while you are implementing, investigating or fixing something." },
|
|
1070
1070
|
{ status_key: "done", label: "Done", color: "#22c55e", icon: "circle-check", sort_order: 4, is_default: 1, agent_settable: 1, prompt: "Set it when the work is completely finished: implemented, validated and with its commit/push done when applicable. It is the final state." },
|
|
1071
|
-
{ status_key: "idle", label: "Idle", color: "#6b7280", icon: "circle-dashed", sort_order: 5, is_default: 1, agent_settable: 0, prompt: "Set by the app
|
|
1071
|
+
{ status_key: "idle", label: "Idle", color: "#6b7280", icon: "circle-dashed", sort_order: 5, is_default: 1, agent_settable: 0, prompt: "Set by the app on an agent that has just been opened and has not been given any work yet. Agents cannot set this status; it clears itself as soon as you send the agent something." }
|
|
1072
1072
|
];
|
|
1073
1073
|
var IDLE_TERMINAL_STATUS_KEY = "idle";
|
|
1074
1074
|
var IDLE_STATUS_SEEDED_SETTING = "terminal_status_idle_seeded";
|
|
@@ -1081,7 +1081,7 @@ var require_database_mcp_standalone = __commonJS({
|
|
|
1081
1081
|
done: 6
|
|
1082
1082
|
};
|
|
1083
1083
|
var LEGACY_DEFAULT_PROMPTS = {
|
|
1084
|
-
idle: "Set by the app
|
|
1084
|
+
idle: "Set by the app when an agent is resting without an explicit work status, including after a reply finishes. It does not mean the work is complete or that user input is required. Agents cannot set this status.",
|
|
1085
1085
|
working: "Ponlo al empezar a trabajar en cualquier petici\xF3n y mientras est\xE9s implementando, investigando o arreglando algo.",
|
|
1086
1086
|
needs_input: "Ponlo cuando pares porque necesites una respuesta o decisi\xF3n del usuario para continuar (una pregunta, una elecci\xF3n de dise\xF1o, un permiso).",
|
|
1087
1087
|
needs_testing: "Ponlo cuando termines la implementaci\xF3n y el trabajo quede pendiente de que el usuario lo pruebe a mano. No lo pongas si a\xFAn quedan cosas por implementar.",
|
package/package.json
CHANGED