replicas-cli 0.2.751 → 0.2.753
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/index.cjs +1106 -596
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -111,17 +111,17 @@ var require_visit = __commonJS({
|
|
|
111
111
|
visit.BREAK = BREAK;
|
|
112
112
|
visit.SKIP = SKIP;
|
|
113
113
|
visit.REMOVE = REMOVE;
|
|
114
|
-
function visit_(key, node, visitor,
|
|
115
|
-
const ctrl = callVisitor(key, node, visitor,
|
|
114
|
+
function visit_(key, node, visitor, path7) {
|
|
115
|
+
const ctrl = callVisitor(key, node, visitor, path7);
|
|
116
116
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
117
|
-
replaceNode(key,
|
|
118
|
-
return visit_(key, ctrl, visitor,
|
|
117
|
+
replaceNode(key, path7, ctrl);
|
|
118
|
+
return visit_(key, ctrl, visitor, path7);
|
|
119
119
|
}
|
|
120
120
|
if (typeof ctrl !== "symbol") {
|
|
121
121
|
if (identity.isCollection(node)) {
|
|
122
|
-
|
|
122
|
+
path7 = Object.freeze(path7.concat(node));
|
|
123
123
|
for (let i = 0; i < node.items.length; ++i) {
|
|
124
|
-
const ci = visit_(i, node.items[i], visitor,
|
|
124
|
+
const ci = visit_(i, node.items[i], visitor, path7);
|
|
125
125
|
if (typeof ci === "number")
|
|
126
126
|
i = ci - 1;
|
|
127
127
|
else if (ci === BREAK)
|
|
@@ -132,13 +132,13 @@ var require_visit = __commonJS({
|
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
} else if (identity.isPair(node)) {
|
|
135
|
-
|
|
136
|
-
const ck = visit_("key", node.key, visitor,
|
|
135
|
+
path7 = Object.freeze(path7.concat(node));
|
|
136
|
+
const ck = visit_("key", node.key, visitor, path7);
|
|
137
137
|
if (ck === BREAK)
|
|
138
138
|
return BREAK;
|
|
139
139
|
else if (ck === REMOVE)
|
|
140
140
|
node.key = null;
|
|
141
|
-
const cv = visit_("value", node.value, visitor,
|
|
141
|
+
const cv = visit_("value", node.value, visitor, path7);
|
|
142
142
|
if (cv === BREAK)
|
|
143
143
|
return BREAK;
|
|
144
144
|
else if (cv === REMOVE)
|
|
@@ -159,17 +159,17 @@ var require_visit = __commonJS({
|
|
|
159
159
|
visitAsync.BREAK = BREAK;
|
|
160
160
|
visitAsync.SKIP = SKIP;
|
|
161
161
|
visitAsync.REMOVE = REMOVE;
|
|
162
|
-
async function visitAsync_(key, node, visitor,
|
|
163
|
-
const ctrl = await callVisitor(key, node, visitor,
|
|
162
|
+
async function visitAsync_(key, node, visitor, path7) {
|
|
163
|
+
const ctrl = await callVisitor(key, node, visitor, path7);
|
|
164
164
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
165
|
-
replaceNode(key,
|
|
166
|
-
return visitAsync_(key, ctrl, visitor,
|
|
165
|
+
replaceNode(key, path7, ctrl);
|
|
166
|
+
return visitAsync_(key, ctrl, visitor, path7);
|
|
167
167
|
}
|
|
168
168
|
if (typeof ctrl !== "symbol") {
|
|
169
169
|
if (identity.isCollection(node)) {
|
|
170
|
-
|
|
170
|
+
path7 = Object.freeze(path7.concat(node));
|
|
171
171
|
for (let i = 0; i < node.items.length; ++i) {
|
|
172
|
-
const ci = await visitAsync_(i, node.items[i], visitor,
|
|
172
|
+
const ci = await visitAsync_(i, node.items[i], visitor, path7);
|
|
173
173
|
if (typeof ci === "number")
|
|
174
174
|
i = ci - 1;
|
|
175
175
|
else if (ci === BREAK)
|
|
@@ -180,13 +180,13 @@ var require_visit = __commonJS({
|
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
182
|
} else if (identity.isPair(node)) {
|
|
183
|
-
|
|
184
|
-
const ck = await visitAsync_("key", node.key, visitor,
|
|
183
|
+
path7 = Object.freeze(path7.concat(node));
|
|
184
|
+
const ck = await visitAsync_("key", node.key, visitor, path7);
|
|
185
185
|
if (ck === BREAK)
|
|
186
186
|
return BREAK;
|
|
187
187
|
else if (ck === REMOVE)
|
|
188
188
|
node.key = null;
|
|
189
|
-
const cv = await visitAsync_("value", node.value, visitor,
|
|
189
|
+
const cv = await visitAsync_("value", node.value, visitor, path7);
|
|
190
190
|
if (cv === BREAK)
|
|
191
191
|
return BREAK;
|
|
192
192
|
else if (cv === REMOVE)
|
|
@@ -213,23 +213,23 @@ var require_visit = __commonJS({
|
|
|
213
213
|
}
|
|
214
214
|
return visitor;
|
|
215
215
|
}
|
|
216
|
-
function callVisitor(key, node, visitor,
|
|
216
|
+
function callVisitor(key, node, visitor, path7) {
|
|
217
217
|
if (typeof visitor === "function")
|
|
218
|
-
return visitor(key, node,
|
|
218
|
+
return visitor(key, node, path7);
|
|
219
219
|
if (identity.isMap(node))
|
|
220
|
-
return visitor.Map?.(key, node,
|
|
220
|
+
return visitor.Map?.(key, node, path7);
|
|
221
221
|
if (identity.isSeq(node))
|
|
222
|
-
return visitor.Seq?.(key, node,
|
|
222
|
+
return visitor.Seq?.(key, node, path7);
|
|
223
223
|
if (identity.isPair(node))
|
|
224
|
-
return visitor.Pair?.(key, node,
|
|
224
|
+
return visitor.Pair?.(key, node, path7);
|
|
225
225
|
if (identity.isScalar(node))
|
|
226
|
-
return visitor.Scalar?.(key, node,
|
|
226
|
+
return visitor.Scalar?.(key, node, path7);
|
|
227
227
|
if (identity.isAlias(node))
|
|
228
|
-
return visitor.Alias?.(key, node,
|
|
228
|
+
return visitor.Alias?.(key, node, path7);
|
|
229
229
|
return void 0;
|
|
230
230
|
}
|
|
231
|
-
function replaceNode(key,
|
|
232
|
-
const parent =
|
|
231
|
+
function replaceNode(key, path7, node) {
|
|
232
|
+
const parent = path7[path7.length - 1];
|
|
233
233
|
if (identity.isCollection(parent)) {
|
|
234
234
|
parent.items[key] = node;
|
|
235
235
|
} else if (identity.isPair(parent)) {
|
|
@@ -839,10 +839,10 @@ var require_Collection = __commonJS({
|
|
|
839
839
|
var createNode = require_createNode();
|
|
840
840
|
var identity = require_identity();
|
|
841
841
|
var Node = require_Node();
|
|
842
|
-
function collectionFromPath(schema,
|
|
842
|
+
function collectionFromPath(schema, path7, value) {
|
|
843
843
|
let v = value;
|
|
844
|
-
for (let i =
|
|
845
|
-
const k =
|
|
844
|
+
for (let i = path7.length - 1; i >= 0; --i) {
|
|
845
|
+
const k = path7[i];
|
|
846
846
|
if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
|
|
847
847
|
const a = [];
|
|
848
848
|
a[k] = v;
|
|
@@ -861,7 +861,7 @@ var require_Collection = __commonJS({
|
|
|
861
861
|
sourceObjects: /* @__PURE__ */ new Map()
|
|
862
862
|
});
|
|
863
863
|
}
|
|
864
|
-
var isEmptyPath = (
|
|
864
|
+
var isEmptyPath = (path7) => path7 == null || typeof path7 === "object" && !!path7[Symbol.iterator]().next().done;
|
|
865
865
|
var Collection = class extends Node.NodeBase {
|
|
866
866
|
constructor(type, schema) {
|
|
867
867
|
super(type);
|
|
@@ -891,11 +891,11 @@ var require_Collection = __commonJS({
|
|
|
891
891
|
* be a Pair instance or a `{ key, value }` object, which may not have a key
|
|
892
892
|
* that already exists in the map.
|
|
893
893
|
*/
|
|
894
|
-
addIn(
|
|
895
|
-
if (isEmptyPath(
|
|
894
|
+
addIn(path7, value) {
|
|
895
|
+
if (isEmptyPath(path7))
|
|
896
896
|
this.add(value);
|
|
897
897
|
else {
|
|
898
|
-
const [key, ...rest] =
|
|
898
|
+
const [key, ...rest] = path7;
|
|
899
899
|
const node = this.get(key, true);
|
|
900
900
|
if (identity.isCollection(node))
|
|
901
901
|
node.addIn(rest, value);
|
|
@@ -909,8 +909,8 @@ var require_Collection = __commonJS({
|
|
|
909
909
|
* Removes a value from the collection.
|
|
910
910
|
* @returns `true` if the item was found and removed.
|
|
911
911
|
*/
|
|
912
|
-
deleteIn(
|
|
913
|
-
const [key, ...rest] =
|
|
912
|
+
deleteIn(path7) {
|
|
913
|
+
const [key, ...rest] = path7;
|
|
914
914
|
if (rest.length === 0)
|
|
915
915
|
return this.delete(key);
|
|
916
916
|
const node = this.get(key, true);
|
|
@@ -924,8 +924,8 @@ var require_Collection = __commonJS({
|
|
|
924
924
|
* scalar values from their surrounding node; to disable set `keepScalar` to
|
|
925
925
|
* `true` (collections are always returned intact).
|
|
926
926
|
*/
|
|
927
|
-
getIn(
|
|
928
|
-
const [key, ...rest] =
|
|
927
|
+
getIn(path7, keepScalar) {
|
|
928
|
+
const [key, ...rest] = path7;
|
|
929
929
|
const node = this.get(key, true);
|
|
930
930
|
if (rest.length === 0)
|
|
931
931
|
return !keepScalar && identity.isScalar(node) ? node.value : node;
|
|
@@ -943,8 +943,8 @@ var require_Collection = __commonJS({
|
|
|
943
943
|
/**
|
|
944
944
|
* Checks if the collection includes a value with the key `key`.
|
|
945
945
|
*/
|
|
946
|
-
hasIn(
|
|
947
|
-
const [key, ...rest] =
|
|
946
|
+
hasIn(path7) {
|
|
947
|
+
const [key, ...rest] = path7;
|
|
948
948
|
if (rest.length === 0)
|
|
949
949
|
return this.has(key);
|
|
950
950
|
const node = this.get(key, true);
|
|
@@ -954,8 +954,8 @@ var require_Collection = __commonJS({
|
|
|
954
954
|
* Sets a value in this collection. For `!!set`, `value` needs to be a
|
|
955
955
|
* boolean to add/remove the item from the set.
|
|
956
956
|
*/
|
|
957
|
-
setIn(
|
|
958
|
-
const [key, ...rest] =
|
|
957
|
+
setIn(path7, value) {
|
|
958
|
+
const [key, ...rest] = path7;
|
|
959
959
|
if (rest.length === 0) {
|
|
960
960
|
this.set(key, value);
|
|
961
961
|
} else {
|
|
@@ -3470,9 +3470,9 @@ var require_Document = __commonJS({
|
|
|
3470
3470
|
this.contents.add(value);
|
|
3471
3471
|
}
|
|
3472
3472
|
/** Adds a value to the document. */
|
|
3473
|
-
addIn(
|
|
3473
|
+
addIn(path7, value) {
|
|
3474
3474
|
if (assertCollection(this.contents))
|
|
3475
|
-
this.contents.addIn(
|
|
3475
|
+
this.contents.addIn(path7, value);
|
|
3476
3476
|
}
|
|
3477
3477
|
/**
|
|
3478
3478
|
* Create a new `Alias` node, ensuring that the target `node` has the required anchor.
|
|
@@ -3547,14 +3547,14 @@ var require_Document = __commonJS({
|
|
|
3547
3547
|
* Removes a value from the document.
|
|
3548
3548
|
* @returns `true` if the item was found and removed.
|
|
3549
3549
|
*/
|
|
3550
|
-
deleteIn(
|
|
3551
|
-
if (Collection.isEmptyPath(
|
|
3550
|
+
deleteIn(path7) {
|
|
3551
|
+
if (Collection.isEmptyPath(path7)) {
|
|
3552
3552
|
if (this.contents == null)
|
|
3553
3553
|
return false;
|
|
3554
3554
|
this.contents = null;
|
|
3555
3555
|
return true;
|
|
3556
3556
|
}
|
|
3557
|
-
return assertCollection(this.contents) ? this.contents.deleteIn(
|
|
3557
|
+
return assertCollection(this.contents) ? this.contents.deleteIn(path7) : false;
|
|
3558
3558
|
}
|
|
3559
3559
|
/**
|
|
3560
3560
|
* Returns item at `key`, or `undefined` if not found. By default unwraps
|
|
@@ -3569,10 +3569,10 @@ var require_Document = __commonJS({
|
|
|
3569
3569
|
* scalar values from their surrounding node; to disable set `keepScalar` to
|
|
3570
3570
|
* `true` (collections are always returned intact).
|
|
3571
3571
|
*/
|
|
3572
|
-
getIn(
|
|
3573
|
-
if (Collection.isEmptyPath(
|
|
3572
|
+
getIn(path7, keepScalar) {
|
|
3573
|
+
if (Collection.isEmptyPath(path7))
|
|
3574
3574
|
return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
|
|
3575
|
-
return identity.isCollection(this.contents) ? this.contents.getIn(
|
|
3575
|
+
return identity.isCollection(this.contents) ? this.contents.getIn(path7, keepScalar) : void 0;
|
|
3576
3576
|
}
|
|
3577
3577
|
/**
|
|
3578
3578
|
* Checks if the document includes a value with the key `key`.
|
|
@@ -3583,10 +3583,10 @@ var require_Document = __commonJS({
|
|
|
3583
3583
|
/**
|
|
3584
3584
|
* Checks if the document includes a value at `path`.
|
|
3585
3585
|
*/
|
|
3586
|
-
hasIn(
|
|
3587
|
-
if (Collection.isEmptyPath(
|
|
3586
|
+
hasIn(path7) {
|
|
3587
|
+
if (Collection.isEmptyPath(path7))
|
|
3588
3588
|
return this.contents !== void 0;
|
|
3589
|
-
return identity.isCollection(this.contents) ? this.contents.hasIn(
|
|
3589
|
+
return identity.isCollection(this.contents) ? this.contents.hasIn(path7) : false;
|
|
3590
3590
|
}
|
|
3591
3591
|
/**
|
|
3592
3592
|
* Sets a value in this document. For `!!set`, `value` needs to be a
|
|
@@ -3603,13 +3603,13 @@ var require_Document = __commonJS({
|
|
|
3603
3603
|
* Sets a value in this document. For `!!set`, `value` needs to be a
|
|
3604
3604
|
* boolean to add/remove the item from the set.
|
|
3605
3605
|
*/
|
|
3606
|
-
setIn(
|
|
3607
|
-
if (Collection.isEmptyPath(
|
|
3606
|
+
setIn(path7, value) {
|
|
3607
|
+
if (Collection.isEmptyPath(path7)) {
|
|
3608
3608
|
this.contents = value;
|
|
3609
3609
|
} else if (this.contents == null) {
|
|
3610
|
-
this.contents = Collection.collectionFromPath(this.schema, Array.from(
|
|
3610
|
+
this.contents = Collection.collectionFromPath(this.schema, Array.from(path7), value);
|
|
3611
3611
|
} else if (assertCollection(this.contents)) {
|
|
3612
|
-
this.contents.setIn(
|
|
3612
|
+
this.contents.setIn(path7, value);
|
|
3613
3613
|
}
|
|
3614
3614
|
}
|
|
3615
3615
|
/**
|
|
@@ -5569,9 +5569,9 @@ var require_cst_visit = __commonJS({
|
|
|
5569
5569
|
visit.BREAK = BREAK;
|
|
5570
5570
|
visit.SKIP = SKIP;
|
|
5571
5571
|
visit.REMOVE = REMOVE;
|
|
5572
|
-
visit.itemAtPath = (cst,
|
|
5572
|
+
visit.itemAtPath = (cst, path7) => {
|
|
5573
5573
|
let item = cst;
|
|
5574
|
-
for (const [field2, index] of
|
|
5574
|
+
for (const [field2, index] of path7) {
|
|
5575
5575
|
const tok = item?.[field2];
|
|
5576
5576
|
if (tok && "items" in tok) {
|
|
5577
5577
|
item = tok.items[index];
|
|
@@ -5580,23 +5580,23 @@ var require_cst_visit = __commonJS({
|
|
|
5580
5580
|
}
|
|
5581
5581
|
return item;
|
|
5582
5582
|
};
|
|
5583
|
-
visit.parentCollection = (cst,
|
|
5584
|
-
const parent = visit.itemAtPath(cst,
|
|
5585
|
-
const field2 =
|
|
5583
|
+
visit.parentCollection = (cst, path7) => {
|
|
5584
|
+
const parent = visit.itemAtPath(cst, path7.slice(0, -1));
|
|
5585
|
+
const field2 = path7[path7.length - 1][0];
|
|
5586
5586
|
const coll = parent?.[field2];
|
|
5587
5587
|
if (coll && "items" in coll)
|
|
5588
5588
|
return coll;
|
|
5589
5589
|
throw new Error("Parent collection not found");
|
|
5590
5590
|
};
|
|
5591
|
-
function _visit(
|
|
5592
|
-
let ctrl = visitor(item,
|
|
5591
|
+
function _visit(path7, item, visitor) {
|
|
5592
|
+
let ctrl = visitor(item, path7);
|
|
5593
5593
|
if (typeof ctrl === "symbol")
|
|
5594
5594
|
return ctrl;
|
|
5595
5595
|
for (const field2 of ["key", "value"]) {
|
|
5596
5596
|
const token = item[field2];
|
|
5597
5597
|
if (token && "items" in token) {
|
|
5598
5598
|
for (let i = 0; i < token.items.length; ++i) {
|
|
5599
|
-
const ci = _visit(Object.freeze(
|
|
5599
|
+
const ci = _visit(Object.freeze(path7.concat([[field2, i]])), token.items[i], visitor);
|
|
5600
5600
|
if (typeof ci === "number")
|
|
5601
5601
|
i = ci - 1;
|
|
5602
5602
|
else if (ci === BREAK)
|
|
@@ -5607,10 +5607,10 @@ var require_cst_visit = __commonJS({
|
|
|
5607
5607
|
}
|
|
5608
5608
|
}
|
|
5609
5609
|
if (typeof ctrl === "function" && field2 === "key")
|
|
5610
|
-
ctrl = ctrl(item,
|
|
5610
|
+
ctrl = ctrl(item, path7);
|
|
5611
5611
|
}
|
|
5612
5612
|
}
|
|
5613
|
-
return typeof ctrl === "function" ? ctrl(item,
|
|
5613
|
+
return typeof ctrl === "function" ? ctrl(item, path7) : ctrl;
|
|
5614
5614
|
}
|
|
5615
5615
|
exports2.visit = visit;
|
|
5616
5616
|
}
|
|
@@ -6912,14 +6912,14 @@ var require_parser = __commonJS({
|
|
|
6912
6912
|
case "scalar":
|
|
6913
6913
|
case "single-quoted-scalar":
|
|
6914
6914
|
case "double-quoted-scalar": {
|
|
6915
|
-
const
|
|
6915
|
+
const fs7 = this.flowScalar(this.type);
|
|
6916
6916
|
if (atNextItem || it.value) {
|
|
6917
|
-
map2.items.push({ start, key:
|
|
6917
|
+
map2.items.push({ start, key: fs7, sep: [] });
|
|
6918
6918
|
this.onKeyLine = true;
|
|
6919
6919
|
} else if (it.sep) {
|
|
6920
|
-
this.stack.push(
|
|
6920
|
+
this.stack.push(fs7);
|
|
6921
6921
|
} else {
|
|
6922
|
-
Object.assign(it, { key:
|
|
6922
|
+
Object.assign(it, { key: fs7, sep: [] });
|
|
6923
6923
|
this.onKeyLine = true;
|
|
6924
6924
|
}
|
|
6925
6925
|
return;
|
|
@@ -7047,13 +7047,13 @@ var require_parser = __commonJS({
|
|
|
7047
7047
|
case "scalar":
|
|
7048
7048
|
case "single-quoted-scalar":
|
|
7049
7049
|
case "double-quoted-scalar": {
|
|
7050
|
-
const
|
|
7050
|
+
const fs7 = this.flowScalar(this.type);
|
|
7051
7051
|
if (!it || it.value)
|
|
7052
|
-
fc.items.push({ start: [], key:
|
|
7052
|
+
fc.items.push({ start: [], key: fs7, sep: [] });
|
|
7053
7053
|
else if (it.sep)
|
|
7054
|
-
this.stack.push(
|
|
7054
|
+
this.stack.push(fs7);
|
|
7055
7055
|
else
|
|
7056
|
-
Object.assign(it, { key:
|
|
7056
|
+
Object.assign(it, { key: fs7, sep: [] });
|
|
7057
7057
|
return;
|
|
7058
7058
|
}
|
|
7059
7059
|
case "flow-map-end":
|
|
@@ -7362,18 +7362,21 @@ var require_dist = __commonJS({
|
|
|
7362
7362
|
});
|
|
7363
7363
|
|
|
7364
7364
|
// src/index.ts
|
|
7365
|
-
var
|
|
7365
|
+
var import_config23 = require("dotenv/config");
|
|
7366
7366
|
var import_node_child_process3 = require("child_process");
|
|
7367
7367
|
var import_commander = require("commander");
|
|
7368
|
-
var
|
|
7368
|
+
var import_chalk25 = __toESM(require("chalk"));
|
|
7369
7369
|
|
|
7370
7370
|
// ../shared/src/urls.ts
|
|
7371
7371
|
var DEFAULT_WEB_APP_URL = "https://app.replicas.dev";
|
|
7372
|
+
var DEFAULT_SUPABASE_URL = "https://mxeqiomwgdgaesecwtct.supabase.co";
|
|
7373
|
+
var DEFAULT_SUPABASE_ANON_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Im14ZXFpb213Z2RnYWVzZWN3dGN0Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTk4OTk2ODAsImV4cCI6MjA3NTQ3NTY4MH0.zLRoK4r9Zep-WaLNkvWcb7DXlJBZFH26QXWO1ljMctM";
|
|
7372
7374
|
var DASHBOARD_PATH = "/dashboard";
|
|
7373
7375
|
var WEB_APP_PATHS = {
|
|
7374
7376
|
home: "/",
|
|
7375
7377
|
onboarding: "/onboarding",
|
|
7376
7378
|
workspaces: "/workspace",
|
|
7379
|
+
environmentSetup: "/workspace/setup",
|
|
7377
7380
|
automations: "/automations",
|
|
7378
7381
|
environment: "/environment",
|
|
7379
7382
|
analytics: "/analytics",
|
|
@@ -7532,6 +7535,9 @@ function isAgentMode() {
|
|
|
7532
7535
|
return false;
|
|
7533
7536
|
}
|
|
7534
7537
|
}
|
|
7538
|
+
function isEnvironmentSetupWorkspace() {
|
|
7539
|
+
return isAgentMode() && !!process.env.REPLICAS_ENVIRONMENT_SETUP_RUN_ID;
|
|
7540
|
+
}
|
|
7535
7541
|
function readAgentConfig() {
|
|
7536
7542
|
if (!import_fs.default.existsSync(CONFIG_FILE)) {
|
|
7537
7543
|
return null;
|
|
@@ -7558,8 +7564,8 @@ var import_supabase_js2 = require("@supabase/supabase-js");
|
|
|
7558
7564
|
|
|
7559
7565
|
// src/lib/supabase.ts
|
|
7560
7566
|
var import_supabase_js = require("@supabase/supabase-js");
|
|
7561
|
-
var supabaseUrl = process.env.REPLICAS_SUPABASE_URL ||
|
|
7562
|
-
var supabaseAnonKey = process.env.REPLICAS_SUPABASE_ANON_KEY ||
|
|
7567
|
+
var supabaseUrl = process.env.REPLICAS_SUPABASE_URL || DEFAULT_SUPABASE_URL;
|
|
7568
|
+
var supabaseAnonKey = process.env.REPLICAS_SUPABASE_ANON_KEY || DEFAULT_SUPABASE_ANON_KEY;
|
|
7563
7569
|
var supabase = (0, import_supabase_js.createClient)(supabaseUrl, supabaseAnonKey, {
|
|
7564
7570
|
auth: {
|
|
7565
7571
|
persistSession: true,
|
|
@@ -7647,6 +7653,9 @@ var import_prompts3 = __toESM(require("prompts"));
|
|
|
7647
7653
|
function isRecord(value) {
|
|
7648
7654
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7649
7655
|
}
|
|
7656
|
+
function isNonEmptyString(value) {
|
|
7657
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
7658
|
+
}
|
|
7650
7659
|
|
|
7651
7660
|
// ../shared/src/json.ts
|
|
7652
7661
|
function safeJsonParse(str, fallback) {
|
|
@@ -8655,10 +8664,10 @@ function mergeDefs(...defs) {
|
|
|
8655
8664
|
function cloneDef(schema) {
|
|
8656
8665
|
return mergeDefs(schema._zod.def);
|
|
8657
8666
|
}
|
|
8658
|
-
function getElementAtPath(obj,
|
|
8659
|
-
if (!
|
|
8667
|
+
function getElementAtPath(obj, path7) {
|
|
8668
|
+
if (!path7)
|
|
8660
8669
|
return obj;
|
|
8661
|
-
return
|
|
8670
|
+
return path7.reduce((acc, key) => acc?.[key], obj);
|
|
8662
8671
|
}
|
|
8663
8672
|
function promiseAllObject(promisesObj) {
|
|
8664
8673
|
const keys = Object.keys(promisesObj);
|
|
@@ -9067,11 +9076,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
9067
9076
|
}
|
|
9068
9077
|
return false;
|
|
9069
9078
|
}
|
|
9070
|
-
function prefixIssues(
|
|
9079
|
+
function prefixIssues(path7, issues) {
|
|
9071
9080
|
return issues.map((iss) => {
|
|
9072
9081
|
var _a3;
|
|
9073
9082
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
9074
|
-
iss.path.unshift(
|
|
9083
|
+
iss.path.unshift(path7);
|
|
9075
9084
|
return iss;
|
|
9076
9085
|
});
|
|
9077
9086
|
}
|
|
@@ -9218,16 +9227,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
|
|
|
9218
9227
|
}
|
|
9219
9228
|
function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
9220
9229
|
const fieldErrors = { _errors: [] };
|
|
9221
|
-
const processError = (error52,
|
|
9230
|
+
const processError = (error52, path7 = []) => {
|
|
9222
9231
|
for (const issue2 of error52.issues) {
|
|
9223
9232
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
9224
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
9233
|
+
issue2.errors.map((issues) => processError({ issues }, [...path7, ...issue2.path]));
|
|
9225
9234
|
} else if (issue2.code === "invalid_key") {
|
|
9226
|
-
processError({ issues: issue2.issues }, [...
|
|
9235
|
+
processError({ issues: issue2.issues }, [...path7, ...issue2.path]);
|
|
9227
9236
|
} else if (issue2.code === "invalid_element") {
|
|
9228
|
-
processError({ issues: issue2.issues }, [...
|
|
9237
|
+
processError({ issues: issue2.issues }, [...path7, ...issue2.path]);
|
|
9229
9238
|
} else {
|
|
9230
|
-
const fullpath = [...
|
|
9239
|
+
const fullpath = [...path7, ...issue2.path];
|
|
9231
9240
|
if (fullpath.length === 0) {
|
|
9232
9241
|
fieldErrors._errors.push(mapper(issue2));
|
|
9233
9242
|
} else {
|
|
@@ -9254,17 +9263,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
|
9254
9263
|
}
|
|
9255
9264
|
function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
9256
9265
|
const result = { errors: [] };
|
|
9257
|
-
const processError = (error52,
|
|
9266
|
+
const processError = (error52, path7 = []) => {
|
|
9258
9267
|
var _a3, _b;
|
|
9259
9268
|
for (const issue2 of error52.issues) {
|
|
9260
9269
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
9261
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
9270
|
+
issue2.errors.map((issues) => processError({ issues }, [...path7, ...issue2.path]));
|
|
9262
9271
|
} else if (issue2.code === "invalid_key") {
|
|
9263
|
-
processError({ issues: issue2.issues }, [...
|
|
9272
|
+
processError({ issues: issue2.issues }, [...path7, ...issue2.path]);
|
|
9264
9273
|
} else if (issue2.code === "invalid_element") {
|
|
9265
|
-
processError({ issues: issue2.issues }, [...
|
|
9274
|
+
processError({ issues: issue2.issues }, [...path7, ...issue2.path]);
|
|
9266
9275
|
} else {
|
|
9267
|
-
const fullpath = [...
|
|
9276
|
+
const fullpath = [...path7, ...issue2.path];
|
|
9268
9277
|
if (fullpath.length === 0) {
|
|
9269
9278
|
result.errors.push(mapper(issue2));
|
|
9270
9279
|
continue;
|
|
@@ -9296,8 +9305,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
|
9296
9305
|
}
|
|
9297
9306
|
function toDotPath(_path) {
|
|
9298
9307
|
const segs = [];
|
|
9299
|
-
const
|
|
9300
|
-
for (const seg of
|
|
9308
|
+
const path7 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
9309
|
+
for (const seg of path7) {
|
|
9301
9310
|
if (typeof seg === "number")
|
|
9302
9311
|
segs.push(`[${seg}]`);
|
|
9303
9312
|
else if (typeof seg === "symbol")
|
|
@@ -21989,13 +21998,13 @@ function resolveRef(ref, ctx) {
|
|
|
21989
21998
|
if (!ref.startsWith("#")) {
|
|
21990
21999
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
21991
22000
|
}
|
|
21992
|
-
const
|
|
21993
|
-
if (
|
|
22001
|
+
const path7 = ref.slice(1).split("/").filter(Boolean);
|
|
22002
|
+
if (path7.length === 0) {
|
|
21994
22003
|
return ctx.rootSchema;
|
|
21995
22004
|
}
|
|
21996
22005
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
21997
|
-
if (
|
|
21998
|
-
const key =
|
|
22006
|
+
if (path7[0] === defsKey) {
|
|
22007
|
+
const key = path7[1];
|
|
21999
22008
|
if (!key || !ctx.defs[key]) {
|
|
22000
22009
|
throw new Error(`Reference not found: ${ref}`);
|
|
22001
22010
|
}
|
|
@@ -23204,11 +23213,11 @@ function parseShellScript(script, cwd) {
|
|
|
23204
23213
|
parseUntil(scope, 0, false);
|
|
23205
23214
|
return scope.commands;
|
|
23206
23215
|
}
|
|
23207
|
-
function resolveShellPath(dir,
|
|
23208
|
-
if (
|
|
23209
|
-
if (!
|
|
23216
|
+
function resolveShellPath(dir, path7) {
|
|
23217
|
+
if (path7.includes(SHELL_OPAQUE) || path7.startsWith("~")) return null;
|
|
23218
|
+
if (!path7.startsWith("/") && dir === null) return null;
|
|
23210
23219
|
const parts = [];
|
|
23211
|
-
for (const part of (
|
|
23220
|
+
for (const part of (path7.startsWith("/") ? path7 : `${dir}/${path7}`).split("/")) {
|
|
23212
23221
|
if (part === "..") parts.pop();
|
|
23213
23222
|
else if (part && part !== ".") parts.push(part);
|
|
23214
23223
|
}
|
|
@@ -23558,16 +23567,16 @@ function parseSkillName(tool, input) {
|
|
|
23558
23567
|
const skillName = parsedInput.skill ?? parsedInput.name;
|
|
23559
23568
|
return typeof skillName === "string" && skillName ? skillName : null;
|
|
23560
23569
|
}
|
|
23561
|
-
function skillNameFromFilePath(
|
|
23562
|
-
const skillName = skillNameFromSkillRootPath(
|
|
23570
|
+
function skillNameFromFilePath(path7) {
|
|
23571
|
+
const skillName = skillNameFromSkillRootPath(path7);
|
|
23563
23572
|
if (skillName) return skillName;
|
|
23564
|
-
const parts =
|
|
23573
|
+
const parts = path7.split(/[\\/]+/).filter(Boolean);
|
|
23565
23574
|
if (parts.length < 2 || parts[parts.length - 1].toLowerCase() !== "skill.md") return null;
|
|
23566
23575
|
const fallbackSkillName = parts[parts.length - 2];
|
|
23567
23576
|
return fallbackSkillName && fallbackSkillName.toLowerCase() !== "skills" ? fallbackSkillName : null;
|
|
23568
23577
|
}
|
|
23569
|
-
function skillNameFromSkillRootPath(
|
|
23570
|
-
const parts =
|
|
23578
|
+
function skillNameFromSkillRootPath(path7) {
|
|
23579
|
+
const parts = path7.split(/[\\/]+/).filter(Boolean);
|
|
23571
23580
|
const skillsIndex = parts.findLastIndex((part) => part.toLowerCase() === "skills");
|
|
23572
23581
|
if (skillsIndex === -1) return null;
|
|
23573
23582
|
const firstSkillPart = parts[skillsIndex + 1];
|
|
@@ -23577,9 +23586,9 @@ function skillNameFromSkillRootPath(path6) {
|
|
|
23577
23586
|
function parseSkillFilePath(input) {
|
|
23578
23587
|
const parsedInput = typeof input === "string" ? safeJsonParse(input, null) : input;
|
|
23579
23588
|
if (!isRecord(parsedInput)) return null;
|
|
23580
|
-
const
|
|
23581
|
-
if (!
|
|
23582
|
-
return skillNameFromFilePath(
|
|
23589
|
+
const path7 = [parsedInput.path, parsedInput.filePath, parsedInput.file_path].find((value) => typeof value === "string" && value.length > 0);
|
|
23590
|
+
if (!path7) return null;
|
|
23591
|
+
return skillNameFromFilePath(path7);
|
|
23583
23592
|
}
|
|
23584
23593
|
function skillNameFromToolCall(tool, input) {
|
|
23585
23594
|
const directSkillName = parseSkillName(tool, input);
|
|
@@ -23891,8 +23900,451 @@ var DOCKER_ABILITY = {
|
|
|
23891
23900
|
referenceFile: { name: "DOCKER.md", content: REFERENCE2 }
|
|
23892
23901
|
};
|
|
23893
23902
|
|
|
23903
|
+
// ../shared/src/uuid.ts
|
|
23904
|
+
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
23905
|
+
|
|
23906
|
+
// ../shared/src/routes/environment-setups.ts
|
|
23907
|
+
var ENVIRONMENT_SETUP_STEPS = [
|
|
23908
|
+
{ key: "understand", label: "Understand the codebase" },
|
|
23909
|
+
{ key: "install", label: "Install dependencies and run the app" },
|
|
23910
|
+
{ key: "verify", label: "Verify checks and record a walkthrough" },
|
|
23911
|
+
{ key: "configure", label: "Draft hooks, system prompt, and automations" },
|
|
23912
|
+
{ key: "propose", label: "Propose the configuration for review" }
|
|
23913
|
+
];
|
|
23914
|
+
var ENVIRONMENT_SETUP_STEP_STATUSES = ["pending", "in_progress", "completed", "skipped"];
|
|
23915
|
+
function isEnvironmentSetupStepKey(value) {
|
|
23916
|
+
return ENVIRONMENT_SETUP_STEPS.some((step) => step.key === value);
|
|
23917
|
+
}
|
|
23918
|
+
function isEnvironmentSetupStepStatus(value) {
|
|
23919
|
+
return ENVIRONMENT_SETUP_STEP_STATUSES.some((status) => status === value);
|
|
23920
|
+
}
|
|
23921
|
+
var ENVIRONMENT_SETUP_RUN_STATUSES = ["running", "proposed", "applied", "failed", "cancelled"];
|
|
23922
|
+
var ENVIRONMENT_SETUP_AUTOMATION_ACTIONS = ["create", "update", "keep", "disable"];
|
|
23923
|
+
var ENVIRONMENT_SETUP_VERIFICATION_STATUSES = ["passed", "failed", "skipped"];
|
|
23924
|
+
var ENVIRONMENT_SETUP_LIMITS = {
|
|
23925
|
+
summaryChars: 600,
|
|
23926
|
+
stackItems: 30,
|
|
23927
|
+
nameChars: 120,
|
|
23928
|
+
descriptionChars: 1e3,
|
|
23929
|
+
systemPromptChars: 2e4,
|
|
23930
|
+
hookChars: 5e4,
|
|
23931
|
+
variables: 50,
|
|
23932
|
+
variableKeyChars: 128,
|
|
23933
|
+
variableDescriptionChars: 500,
|
|
23934
|
+
automations: 8,
|
|
23935
|
+
automationKeyChars: 80,
|
|
23936
|
+
automationPromptChars: 1e4,
|
|
23937
|
+
automationTriggers: 5,
|
|
23938
|
+
automationNoteChars: 300,
|
|
23939
|
+
verificationItems: 8,
|
|
23940
|
+
verificationDetailChars: 300,
|
|
23941
|
+
mediaItems: 8,
|
|
23942
|
+
repositories: 20
|
|
23943
|
+
};
|
|
23944
|
+
var ENVIRONMENT_SETUP_VARIABLE_WAIT = { defaultMs: 5 * 6e4, maxMs: 15 * 6e4, pollMs: 5e3 };
|
|
23945
|
+
var VARIABLE_KEY_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
23946
|
+
var text = (max) => max === void 0 ? external_exports.string().trim() : external_exports.string().trim().max(max);
|
|
23947
|
+
var requiredText = (max) => text(max).min(1, "must not be empty");
|
|
23948
|
+
var optionalText = (max) => text(max).nullish().transform((value) => value || null);
|
|
23949
|
+
var clearableText = (max) => text(max).nullish().transform((value) => value === void 0 ? void 0 : value || null);
|
|
23950
|
+
var list = (item, max) => max === void 0 ? external_exports.array(item) : external_exports.array(item).max(max);
|
|
23951
|
+
var ENVIRONMENT_SETUP_AUTHORED_TRIGGER_TYPES = ["cron", "github", "gitlab"];
|
|
23952
|
+
function isEnvironmentSetupAuthoredTriggerType(type) {
|
|
23953
|
+
return ENVIRONMENT_SETUP_AUTHORED_TRIGGER_TYPES.some((authored) => authored === type);
|
|
23954
|
+
}
|
|
23955
|
+
var repositoryTriggerConfigSchema = external_exports.object({
|
|
23956
|
+
event: external_exports.string(),
|
|
23957
|
+
repository_ids: external_exports.array(external_exports.string().regex(UUID_RE, "must be a repository id")).optional(),
|
|
23958
|
+
group_pr_events: external_exports.boolean().optional(),
|
|
23959
|
+
excluded_actors: external_exports.array(external_exports.string()).optional()
|
|
23960
|
+
});
|
|
23961
|
+
var proposalTriggerSchema = external_exports.discriminatedUnion("type", [
|
|
23962
|
+
external_exports.object({ type: external_exports.literal("cron"), config: external_exports.object({ schedule: external_exports.string(), timezone: external_exports.string().optional() }) }),
|
|
23963
|
+
external_exports.object({ type: external_exports.literal("github"), config: repositoryTriggerConfigSchema }),
|
|
23964
|
+
external_exports.object({ type: external_exports.literal("gitlab"), config: repositoryTriggerConfigSchema })
|
|
23965
|
+
]);
|
|
23966
|
+
var existingTriggerSchema = external_exports.custom(
|
|
23967
|
+
(value) => isRecord(value) && typeof value.type === "string" && isRecord(value.config),
|
|
23968
|
+
"must be an automation trigger"
|
|
23969
|
+
);
|
|
23970
|
+
var carriedTriggerSchema = existingTriggerSchema.refine(
|
|
23971
|
+
(trigger) => !isEnvironmentSetupAuthoredTriggerType(trigger.type)
|
|
23972
|
+
);
|
|
23973
|
+
function automationSchema(limits) {
|
|
23974
|
+
const authored = external_exports.object({
|
|
23975
|
+
name: text(limits.nameChars),
|
|
23976
|
+
description: text(limits.descriptionChars),
|
|
23977
|
+
prompt: text(limits.automationPromptChars),
|
|
23978
|
+
triggers: list(proposalTriggerSchema, limits.automationTriggers)
|
|
23979
|
+
});
|
|
23980
|
+
const updated = authored.extend({ triggers: list(external_exports.union([proposalTriggerSchema, carriedTriggerSchema]), limits.automationTriggers) });
|
|
23981
|
+
return external_exports.object({
|
|
23982
|
+
key: requiredText(limits.automationKeyChars),
|
|
23983
|
+
action: external_exports.enum(ENVIRONMENT_SETUP_AUTOMATION_ACTIONS).default("create"),
|
|
23984
|
+
automation_id: external_exports.string().regex(UUID_RE, "must be an automation id").nullable().default(null),
|
|
23985
|
+
name: text().default(""),
|
|
23986
|
+
description: optionalText().transform((value) => value ?? ""),
|
|
23987
|
+
prompt: text().default(""),
|
|
23988
|
+
triggers: list(existingTriggerSchema).default([]),
|
|
23989
|
+
note: optionalText(limits.automationNoteChars)
|
|
23990
|
+
}).superRefine((automation2, ctx) => {
|
|
23991
|
+
if (automation2.action === "create" && automation2.automation_id) {
|
|
23992
|
+
ctx.addIssue({ code: "custom", path: ["automation_id"], message: "belongs on an update, keep, or disable entry" });
|
|
23993
|
+
}
|
|
23994
|
+
if (automation2.action !== "create" && !automation2.automation_id) {
|
|
23995
|
+
ctx.addIssue({ code: "custom", path: ["automation_id"], message: "must be the id of an automation attached to this environment" });
|
|
23996
|
+
}
|
|
23997
|
+
if (automation2.action === "create" || automation2.action === "update") {
|
|
23998
|
+
if (!automation2.name) ctx.addIssue({ code: "custom", path: ["name"], message: "must not be empty" });
|
|
23999
|
+
if (!automation2.prompt) ctx.addIssue({ code: "custom", path: ["prompt"], message: "must not be empty" });
|
|
24000
|
+
if (automation2.triggers.length === 0) ctx.addIssue({ code: "custom", path: ["triggers"], message: "must not be empty" });
|
|
24001
|
+
}
|
|
24002
|
+
}).transform((automation2, ctx) => {
|
|
24003
|
+
if (automation2.action === "keep" || automation2.action === "disable") return automation2;
|
|
24004
|
+
const content = (automation2.action === "update" ? updated : authored).safeParse(automation2);
|
|
24005
|
+
if (content.success) return { ...automation2, ...content.data };
|
|
24006
|
+
for (const issue2 of content.error.issues) ctx.addIssue({ ...issue2, code: "custom" });
|
|
24007
|
+
return external_exports.NEVER;
|
|
24008
|
+
});
|
|
24009
|
+
}
|
|
24010
|
+
function automationListSchema(limits) {
|
|
24011
|
+
return list(automationSchema(limits)).default([]).superRefine((automations, ctx) => {
|
|
24012
|
+
if (new Set(automations.map((automation2) => automation2.key)).size !== automations.length) {
|
|
24013
|
+
ctx.addIssue({ code: "custom", message: "must have unique keys" });
|
|
24014
|
+
}
|
|
24015
|
+
const targets = automations.flatMap((automation2) => automation2.automation_id ?? []);
|
|
24016
|
+
if (new Set(targets).size !== targets.length) {
|
|
24017
|
+
ctx.addIssue({ code: "custom", message: "must mention each existing automation once" });
|
|
24018
|
+
}
|
|
24019
|
+
if (limits.automations !== void 0 && automations.filter((automation2) => automation2.action === "create").length > limits.automations) {
|
|
24020
|
+
ctx.addIssue({ code: "custom", message: `must create at most ${limits.automations} new automations` });
|
|
24021
|
+
}
|
|
24022
|
+
});
|
|
24023
|
+
}
|
|
24024
|
+
function environmentSchema(limits) {
|
|
24025
|
+
return external_exports.object({
|
|
24026
|
+
name: optionalText(limits.nameChars).transform((value) => value ?? void 0),
|
|
24027
|
+
description: clearableText(limits.descriptionChars),
|
|
24028
|
+
system_prompt: clearableText(limits.systemPromptChars),
|
|
24029
|
+
start_hook: clearableText(limits.hookChars),
|
|
24030
|
+
warm_hook: clearableText(limits.hookChars)
|
|
24031
|
+
});
|
|
24032
|
+
}
|
|
24033
|
+
function variableSchema(limits, requiredDefault) {
|
|
24034
|
+
return external_exports.object({
|
|
24035
|
+
key: external_exports.string().regex(VARIABLE_KEY_RE, "must be a valid environment variable name").max(limits.variableKeyChars ?? Number.POSITIVE_INFINITY),
|
|
24036
|
+
description: optionalText(limits.variableDescriptionChars).transform((value) => value ?? ""),
|
|
24037
|
+
required: external_exports.boolean().default(requiredDefault)
|
|
24038
|
+
});
|
|
24039
|
+
}
|
|
24040
|
+
function proposalSchema(limits) {
|
|
24041
|
+
return external_exports.object({
|
|
24042
|
+
summary: requiredText(limits.summaryChars),
|
|
24043
|
+
stack: list(text(), limits.stackItems).default([]).transform((items) => items.filter(Boolean)),
|
|
24044
|
+
environment: environmentSchema(limits),
|
|
24045
|
+
variables: list(variableSchema(limits, false), limits.variables).default([]),
|
|
24046
|
+
automations: automationListSchema(limits),
|
|
24047
|
+
verification: list(external_exports.object({
|
|
24048
|
+
label: requiredText(limits.nameChars),
|
|
24049
|
+
status: external_exports.enum(ENVIRONMENT_SETUP_VERIFICATION_STATUSES),
|
|
24050
|
+
detail: optionalText(limits.verificationDetailChars).transform((value) => value ?? void 0)
|
|
24051
|
+
}), limits.verificationItems).default([]),
|
|
24052
|
+
media: list(external_exports.object({
|
|
24053
|
+
media_id: external_exports.string().regex(UUID_RE, "must be a media id"),
|
|
24054
|
+
title: requiredText(limits.nameChars)
|
|
24055
|
+
}), limits.mediaItems).default([])
|
|
24056
|
+
});
|
|
24057
|
+
}
|
|
24058
|
+
var environmentSetupProposalSchema = proposalSchema({});
|
|
24059
|
+
var environmentSetupProposalSubmissionSchema = proposalSchema(ENVIRONMENT_SETUP_LIMITS);
|
|
24060
|
+
var environmentSetupVariableRequestSchema = variableSchema({}, false).extend({
|
|
24061
|
+
status: external_exports.enum(["pending", "provided", "skipped"]),
|
|
24062
|
+
requested_at: external_exports.string(),
|
|
24063
|
+
resolved_at: external_exports.string().nullable().default(null)
|
|
24064
|
+
});
|
|
24065
|
+
var environmentSetupRunStateSchema = external_exports.object({
|
|
24066
|
+
status: external_exports.enum(ENVIRONMENT_SETUP_RUN_STATUSES),
|
|
24067
|
+
steps: external_exports.partialRecord(external_exports.enum(ENVIRONMENT_SETUP_STEPS.map((step) => step.key)), external_exports.enum(ENVIRONMENT_SETUP_STEP_STATUSES)).default({}),
|
|
24068
|
+
proposal: environmentSetupProposalSchema.nullable().default(null),
|
|
24069
|
+
applied: external_exports.object({
|
|
24070
|
+
applied_at: external_exports.string(),
|
|
24071
|
+
automation_ids: external_exports.array(external_exports.string())
|
|
24072
|
+
}).nullable().default(null),
|
|
24073
|
+
variable_requests: external_exports.array(environmentSetupVariableRequestSchema).default([])
|
|
24074
|
+
});
|
|
24075
|
+
var applyEnvironmentSetupRequestSchema = external_exports.object({
|
|
24076
|
+
environment: environmentSchema(ENVIRONMENT_SETUP_LIMITS).extend({ name: requiredText(ENVIRONMENT_SETUP_LIMITS.nameChars) }),
|
|
24077
|
+
variables: list(external_exports.object({ key: external_exports.string().regex(VARIABLE_KEY_RE), value: external_exports.string() }), ENVIRONMENT_SETUP_LIMITS.variables).default([]).refine((variables) => new Set(variables.map((variable) => variable.key)).size === variables.length, "must have unique keys").transform((variables) => variables.filter((variable) => variable.value.length > 0)),
|
|
24078
|
+
automations: automationListSchema(ENVIRONMENT_SETUP_LIMITS)
|
|
24079
|
+
});
|
|
24080
|
+
var requestEnvironmentSetupVariablesSchema = external_exports.object({
|
|
24081
|
+
variables: list(variableSchema(ENVIRONMENT_SETUP_LIMITS, true), ENVIRONMENT_SETUP_LIMITS.variables).min(1, "must not be empty")
|
|
24082
|
+
}).superRefine(({ variables }, ctx) => {
|
|
24083
|
+
if (new Set(variables.map((variable) => variable.key)).size !== variables.length) {
|
|
24084
|
+
ctx.addIssue({ code: "custom", path: ["variables"], message: "must have unique keys" });
|
|
24085
|
+
}
|
|
24086
|
+
});
|
|
24087
|
+
var respondEnvironmentSetupVariablesSchema = external_exports.object({
|
|
24088
|
+
values: external_exports.record(external_exports.string().regex(VARIABLE_KEY_RE), external_exports.string()).default({}),
|
|
24089
|
+
skipped: external_exports.array(external_exports.string().regex(VARIABLE_KEY_RE)).default([])
|
|
24090
|
+
});
|
|
24091
|
+
|
|
24092
|
+
// ../shared/src/default-skills/replicas-agent/abilities/environment-setup.ts
|
|
24093
|
+
var SECTION3 = `### Environment setup (agent-led)
|
|
24094
|
+
Explore a codebase, get it running in this workspace, verify it end to end, and propose the Replicas environment configuration (start hook, warm hook, system prompt, variables) plus a few automations for the user to review and save.
|
|
24095
|
+
|
|
24096
|
+
**Reference:** \`references/ENVIRONMENT-SETUP.md\`
|
|
24097
|
+
|
|
24098
|
+
Use this when:
|
|
24099
|
+
- This workspace was started as an environment setup run (\`replicas environment-setup status\` succeeds)
|
|
24100
|
+
- The user asks you to set up, configure, audit, or improve a Replicas environment for a repository
|
|
24101
|
+
- The user asks what should go in a start hook, warm hook, or environment system prompt`;
|
|
24102
|
+
var REFERENCE3 = `# Environment setup (agent-led)
|
|
24103
|
+
|
|
24104
|
+
Use this workflow to make a repository fully usable by Replicas background agents: agents booted from the environment should be able to install, run, test, verify, and demo changes without a human babysitting them. The result of the workflow is a **proposal**, never a direct change: the user reviews, edits, and saves it in the Environment panel next to the chat.
|
|
24105
|
+
|
|
24106
|
+
## Mental model
|
|
24107
|
+
|
|
24108
|
+
Every Replicas workspace is a remote Linux VM. Repositories are cloned under \`~/workspaces/<repo-name>\`. An **environment** is the org-scoped template a workspace is built from. It binds one repository (or a repository set for monorepos and multi-repo stacks) and carries:
|
|
24109
|
+
|
|
24110
|
+
| Piece | When it runs | Put here |
|
|
24111
|
+
| --- | --- | --- |
|
|
24112
|
+
| **Warm hook** | Once, while Replicas builds the warm-pool snapshot for the environment. Its *filesystem* state is baked into every new workspace; its *processes* are not. Default timeout 60 minutes. | Slow, deterministic setup: dependency installs from the lockfile, toolchain downloads, \`docker pull\`, one-time builds, code generation. |
|
|
24113
|
+
| **Start hook** | On every workspace boot, before the agent starts working. Default timeout 5 minutes. | Fast per-boot reconciliation: start daemons and databases, run migrations against local services, launch dev servers with \`replicas service start\`, health checks. Must be idempotent. |
|
|
24114
|
+
| **System prompt** | Injected into the agent's instructions for every workspace in the environment. | Only what an agent cannot learn from the repository itself: team conventions, review expectations, how to verify, gotchas you hit while setting up. |
|
|
24115
|
+
| **Variables** | Exported into every workspace (and available inside hooks). Values are encrypted. | API keys, tokens, feature flags, local service URLs. |
|
|
24116
|
+
| **Files** | Materialized on the workspace filesystem at boot. | \`.env\` files, dotfiles, config that must not be committed. |
|
|
24117
|
+
| **Automations** | Saved prompts fired by triggers (cron, pull request events, Slack, Sentry, webhooks). Each run creates a workspace in an environment. | Recurring engineering work that fits this repository. |
|
|
24118
|
+
|
|
24119
|
+
Hooks run with \`bash -lc\` from \`~/workspaces\` (the parent of every repository checkout), so start scripts with \`cd ~/workspaces/<repo-name>\`. A repository may also ship its own \`replicas.json\` / \`replicas.yaml\` with \`startHook\`, \`warmHook\`, and \`systemPrompt\`; repository hooks run after the environment hooks. Prefer proposing environment hooks unless the repository already manages its own.
|
|
24120
|
+
|
|
24121
|
+
The Global environment applies to every workspace in the organization; never propose putting repository-specific setup there.
|
|
24122
|
+
|
|
24123
|
+
## Progress and the setup run
|
|
24124
|
+
|
|
24125
|
+
When this workspace was started as a setup run, the dashboard shows a live checklist next to the chat. Keep it honest with:
|
|
24126
|
+
|
|
24127
|
+
\`\`\`bash
|
|
24128
|
+
replicas environment-setup status
|
|
24129
|
+
replicas environment-setup step <key> <status>
|
|
24130
|
+
replicas environment-setup request-variables -f <path>
|
|
24131
|
+
replicas environment-setup wait-variables [-t 5m]
|
|
24132
|
+
\`\`\`
|
|
24133
|
+
|
|
24134
|
+
\`status\` prints the environment, repositories, current steps, and variable requests. \`request-variables\` returns immediately; \`wait-variables\` blocks until the required values arrive, are skipped, or the time runs out. Step statuses are \`pending\`, \`in_progress\`, \`completed\`, and \`skipped\`. Step keys, in order: \`understand\`, \`install\`, \`verify\`, \`configure\`, \`propose\`. Mark the first step \`in_progress\` before your first tool call, keep exactly one step \`in_progress\`, and mark a step \`completed\` only after its work actually succeeded. Use \`skipped\` when something genuinely cannot run (for example no browser UI to record) and say so in the proposal.
|
|
24135
|
+
|
|
24136
|
+
If \`replicas environment-setup status\` reports that there is no active setup run, the user asked for this in an ordinary workspace. Follow the same discovery and verification steps, then present the configuration in chat; apply it with \`replicas environment ...\` and \`replicas automation ...\` only when the user explicitly asks you to.
|
|
24137
|
+
|
|
24138
|
+
## 1. Understand the codebase
|
|
24139
|
+
|
|
24140
|
+
Investigate in parallel before changing anything:
|
|
24141
|
+
|
|
24142
|
+
1. Identify the products and services in the repository. Separate what is required for an end-to-end development flow from what is optional.
|
|
24143
|
+
2. Read setup entry points: \`README\`, \`CONTRIBUTING\`, \`AGENTS.md\`, \`CLAUDE.md\`, package-manager files, tool-version files (\`.nvmrc\`, \`.tool-versions\`, \`.python-version\`), Makefiles, setup scripts, devcontainer and Docker Compose files, CI workflows.
|
|
24144
|
+
3. Find the canonical install, dev-server, lint, type-check, test, and build commands. CI workflows and pre-commit hooks encode the checks that matter.
|
|
24145
|
+
4. Learn the team's conventions from history: \`git log --oneline -50\`, and \`gh pr list --state merged --limit 20\` plus \`gh pr view <n>\` on a few merged pull requests (or the GitLab equivalents). Note branch naming, commit style, review expectations, and recurring chores that could become automations.
|
|
24146
|
+
5. Identify required secrets, test accounts, databases, queues, browser dependencies, and external services. Check \`.env.example\`, config loaders, and CI secrets for variable names. Never read or print secret values. As soon as you know the names, ask for them (see "Asking for variables") and keep going.
|
|
24147
|
+
6. Inspect any existing \`replicas.json\` and the current environment (\`replicas environment get <name>\`, \`replicas environment start-hooks get <name>\`, \`replicas environment warm-hooks get <name>\`) so the proposal builds on what exists instead of competing with it. List the organization's automations with \`replicas automation list --owner org\` and read each one attached to this environment with \`replicas automation get <id>\` (the environment id is in \`replicas environment-setup status\`); every one of them needs a decision in the proposal.
|
|
24148
|
+
|
|
24149
|
+
Use subagents for broad, independent analysis when available, but read the files and run the commands yourself before adopting their conclusions.
|
|
24150
|
+
|
|
24151
|
+
## Asking for variables
|
|
24152
|
+
|
|
24153
|
+
The user may be watching the panel or may have walked away, so ask early and wait late:
|
|
24154
|
+
|
|
24155
|
+
1. Right after step 1, request every secret you found in one batch. \`required\` means the app cannot run locally without it; leave it \`false\` for anything you can work around.
|
|
24156
|
+
|
|
24157
|
+
\`\`\`bash
|
|
24158
|
+
replicas environment-setup request-variables --file /tmp/variables.json
|
|
24159
|
+
\`\`\`
|
|
24160
|
+
|
|
24161
|
+
\`\`\`json
|
|
24162
|
+
{
|
|
24163
|
+
"variables": [
|
|
24164
|
+
{ "key": "DATABASE_URL", "description": "Postgres connection string; a local docker compose database works", "required": false },
|
|
24165
|
+
{ "key": "STRIPE_SECRET_KEY", "description": "Stripe test-mode key; checkout cannot run without it", "required": true }
|
|
24166
|
+
]
|
|
24167
|
+
}
|
|
24168
|
+
\`\`\`
|
|
24169
|
+
|
|
24170
|
+
2. Keep working on everything that does not need the values. The request appears in the Environment panel next to the chat; the user types values there (stored encrypted on the environment, never in chat) or skips them.
|
|
24171
|
+
3. At the point you actually need a value, block on it:
|
|
24172
|
+
|
|
24173
|
+
\`\`\`bash
|
|
24174
|
+
replicas environment-setup wait-variables --timeout 5m
|
|
24175
|
+
replicas environment-setup wait-variables --keys STRIPE_SECRET_KEY
|
|
24176
|
+
\`\`\`
|
|
24177
|
+
|
|
24178
|
+
Without \`--keys\` it waits for every pending required key. It returns when the keys are provided or skipped, or when the time runs out, and prints which happened. Provided keys are exported for every new shell; restart anything you started with \`replicas service start\` before that point so it picks them up. Never print the values.
|
|
24179
|
+
4. For anything skipped or unanswered, use the safest local substitute (local database, mock, documented test value), say so in the verification rows, and list the key as required in the proposal. A key the user skipped is not asked again; do not resend it.
|
|
24180
|
+
5. Values the user provided are already saved on the environment. Still list those keys in the proposal so the review shows them as set.
|
|
24181
|
+
6. Requests are only accepted before you propose. Anything still missing after that goes into the proposal as a required variable, which the user fills in at review.
|
|
24182
|
+
|
|
24183
|
+
## 2. Install and run
|
|
24184
|
+
|
|
24185
|
+
Work from the smallest failing layer, in this workspace:
|
|
24186
|
+
|
|
24187
|
+
1. Install system dependencies and toolchains the repository pins.
|
|
24188
|
+
2. Run the install command to completion, then run it a second time to prove idempotence.
|
|
24189
|
+
3. Start infrastructure and long-running processes with \`replicas service start <name> "<command>"\` so they survive turn boundaries (see \`REPLICAS.md\`). Start the Docker daemon first if Compose is involved (see \`DOCKER.md\`).
|
|
24190
|
+
4. Run the canonical lint, type-check, test, and build commands for the agreed scope. Record what passed, what failed, and why.
|
|
24191
|
+
|
|
24192
|
+
Use the repository's pinned package manager and lockfile. Do not upgrade dependencies, rewrite lockfiles, or change application code to make setup pass; environment configuration and narrowly necessary fixes to setup scripts are in scope. Do not deploy, publish, or touch production resources.
|
|
24193
|
+
|
|
24194
|
+
When something needs a secret you do not have, request it and run \`wait-variables\` at the point you need it (see "Asking for variables"). If it is skipped or unanswered, use the safest local substitute, keep going, and record the variable as required in the proposal with a clear description. Never invent or paste secret values anywhere.
|
|
24195
|
+
|
|
24196
|
+
## 3. Verify and record
|
|
24197
|
+
|
|
24198
|
+
Loading a page is not verification. Perform a representative real action through the product: create a record, submit a form, run a CLI command against the running service, call an endpoint and check the response.
|
|
24199
|
+
|
|
24200
|
+
For anything with a UI, record it:
|
|
24201
|
+
|
|
24202
|
+
\`\`\`bash
|
|
24203
|
+
replicas computer record start /tmp/walkthrough.mp4
|
|
24204
|
+
replicas computer launch chrome http://localhost:<port>
|
|
24205
|
+
replicas computer browser-state /tmp/state.png --full
|
|
24206
|
+
replicas computer browser-click "<button that starts the core flow>"
|
|
24207
|
+
replicas computer record stop
|
|
24208
|
+
replicas media upload /tmp/walkthrough.mp4 --name "<Project> walkthrough"
|
|
24209
|
+
\`\`\`
|
|
24210
|
+
|
|
24211
|
+
Keep the recording short (one to three minutes) and focused on the flow that proves the environment works. \`replicas media upload\` prints a chat embed line and a \`View in Replicas\` link ending in \`?media=<media-id>\`; keep both. The media id goes into the proposal, and the embed line goes into your final message. Follow \`MEDIA.md\` for anything shared outside the dashboard.
|
|
24212
|
+
|
|
24213
|
+
Add screenshots of important states (a passing test run, the running app) with \`replicas computer screenshot\` and upload them the same way when they help the user trust the result.
|
|
24214
|
+
|
|
24215
|
+
## 4. Draft the configuration
|
|
24216
|
+
|
|
24217
|
+
Design from what you verified, not from what the README promises.
|
|
24218
|
+
|
|
24219
|
+
**Warm hook** \u2014 everything slow and deterministic that produced files on disk during step 2: dependency install, toolchain setup, \`docker compose pull\`, one-time builds, code generation. Non-interactive, \`set -euo pipefail\`, safe to rerun.
|
|
24220
|
+
|
|
24221
|
+
**Start hook** \u2014 everything that must be alive when an agent starts: start Docker, start databases and caches, run migrations, launch dev servers with \`replicas service start\`, then wait for readiness (poll a health endpoint) and exit 0. Guard every step so a second run is a no-op. Keep it under a couple of minutes; anything heavier belongs in the warm hook.
|
|
24222
|
+
|
|
24223
|
+
**System prompt** \u2014 short, and only for what is not obvious from the repository. Agents read the README, CONTRIBUTING, AGENTS.md, and CLAUDE.md themselves, so do not repeat what the product is, how the code is organized, or the standard commands. Include what you learned from history and from running the app: commit and pull request style, review expectations, what to run before opening a pull request, how to verify a change (ports, non-secret test accounts), and gotchas that cost you time. Aim for under 200 words. Use \`null\` when the repository docs already cover everything. Never include secrets or anything Replicas already tells the agent.
|
|
24224
|
+
|
|
24225
|
+
**Variables** \u2014 every key the application or hooks need, with a one-line description and whether it is required to run locally. Keys only, never values.
|
|
24226
|
+
|
|
24227
|
+
**Automations** \u2014 the set that should exist for this repository after saving, usually two to four. Each entry has a \`key\` and an \`action\`. \`create\` (the default) adds a new automation and needs a name, one-sentence description, a complete prompt an agent can execute unattended, and triggers. For an automation that already exists, pass its \`automation_id\` and a one-sentence \`note\` the reviewer sees next to it, then choose: \`update\` rewrites it with the full new content (also how you replace it with something better, under a new name if needed), \`keep\` leaves it untouched, \`disable\` turns it off. Every automation already attached to the environment must appear with one of those three; ones you leave out are not shown to the reviewer. Good candidates for new ones: pull request review focused on this codebase's conventions (\`pull_request.opened\` + \`pull_request.synchronize\`), nightly or weekly health checks (cron), documentation sync when code changes, dependency or security review, flaky-test triage. Only propose what the repository evidence supports.
|
|
24228
|
+
|
|
24229
|
+
Trigger shapes:
|
|
24230
|
+
|
|
24231
|
+
\`\`\`json
|
|
24232
|
+
{ "type": "github", "config": { "event": "pull_request.opened" } }
|
|
24233
|
+
{ "type": "github", "config": { "event": "pull_request.synchronize", "excluded_actors": ["dependabot[bot]"] } }
|
|
24234
|
+
{ "type": "gitlab", "config": { "event": "merge_request.opened" } }
|
|
24235
|
+
{ "type": "cron", "config": { "schedule": "0 9 * * 1-5", "timezone": "UTC" } }
|
|
24236
|
+
\`\`\`
|
|
24237
|
+
|
|
24238
|
+
GitHub events: \`pull_request.opened\`, \`pull_request.synchronize\`, \`pull_request.merged\`, \`pull_request.closed\`. GitLab events: \`merge_request.opened\`, \`merge_request.updated\`, \`merge_request.merged\`, \`merge_request.closed\`. Use one trigger type family per automation and pick the code host the repositories actually live on.
|
|
24239
|
+
|
|
24240
|
+
Test the hooks before proposing them: run the drafted warm hook and start hook scripts in this workspace (from \`~/workspaces\`) and fix the earliest failure until both exit 0 on a second run.
|
|
24241
|
+
|
|
24242
|
+
## 5. Propose
|
|
24243
|
+
|
|
24244
|
+
The \`summary\` and \`verification\` fields are read by a person in the Environment panel, so write them for a person:
|
|
24245
|
+
|
|
24246
|
+
- \`summary\`: two or three plain sentences. What the product is, what it takes to run it, and anything notable you found. No command names, file paths, or version numbers; those belong in the system prompt or in verification details.
|
|
24247
|
+
- \`verification\`: three to six rows, one per outcome, in plain words. Group related commands into one row ("Installed and built the app", "Ran the unit and browser tests") and keep each \`detail\` to one sentence with the specifics. Never use a raw command as a label.
|
|
24248
|
+
- Limits, enforced by \`propose\`: \`summary\` ${ENVIRONMENT_SETUP_LIMITS.summaryChars} characters; \`verification\` ${ENVIRONMENT_SETUP_LIMITS.verificationItems} rows with \`detail\` ${ENVIRONMENT_SETUP_LIMITS.verificationDetailChars} characters each; \`stack\` ${ENVIRONMENT_SETUP_LIMITS.stackItems} items; \`variables\` ${ENVIRONMENT_SETUP_LIMITS.variables}, descriptions ${ENVIRONMENT_SETUP_LIMITS.variableDescriptionChars} characters; \`automations\` ${ENVIRONMENT_SETUP_LIMITS.automations} new ones (decisions on existing automations do not count), each with ${ENVIRONMENT_SETUP_LIMITS.automationTriggers} triggers, a ${ENVIRONMENT_SETUP_LIMITS.automationPromptChars}-character prompt, and a ${ENVIRONMENT_SETUP_LIMITS.automationNoteChars}-character note; \`media\` ${ENVIRONMENT_SETUP_LIMITS.mediaItems} items; \`system_prompt\` ${ENVIRONMENT_SETUP_LIMITS.systemPromptChars} characters; each hook ${ENVIRONMENT_SETUP_LIMITS.hookChars} characters; names ${ENVIRONMENT_SETUP_LIMITS.nameChars} and \`description\` ${ENVIRONMENT_SETUP_LIMITS.descriptionChars} characters.
|
|
24249
|
+
|
|
24250
|
+
Write the proposal to a file and submit it:
|
|
24251
|
+
|
|
24252
|
+
\`\`\`bash
|
|
24253
|
+
replicas environment-setup propose --file /tmp/proposal.json
|
|
24254
|
+
\`\`\`
|
|
24255
|
+
|
|
24256
|
+
\`\`\`json
|
|
24257
|
+
{
|
|
24258
|
+
"summary": "An online storefront: a Next.js site backed by a small Bun API and a Postgres database. Everything runs locally with Docker Compose and no external accounts. Payments are optional and stay disabled without a Stripe test key.",
|
|
24259
|
+
"stack": ["Bun", "Next.js", "Postgres", "Docker Compose", "Vitest"],
|
|
24260
|
+
"environment": {
|
|
24261
|
+
"description": "Storefront web app and API",
|
|
24262
|
+
"system_prompt": "Pull requests use conventional commit titles (feat:, fix:, chore:) and need a passing \`bun run check\` before review. Verify UI changes in the browser at http://localhost:3000 with the seeded account listed in docs/testing.md; the API is on port 4000. Database changes go through a migration in db/migrations, never a direct schema edit.",
|
|
24263
|
+
"start_hook": "#!/usr/bin/env bash\\nset -euo pipefail\\n...",
|
|
24264
|
+
"warm_hook": "#!/usr/bin/env bash\\nset -euo pipefail\\n..."
|
|
24265
|
+
},
|
|
24266
|
+
"variables": [
|
|
24267
|
+
{ "key": "STRIPE_SECRET_KEY", "description": "Stripe test-mode key used by checkout; omit to run with payments disabled", "required": false }
|
|
24268
|
+
],
|
|
24269
|
+
"automations": [
|
|
24270
|
+
{
|
|
24271
|
+
"key": "pr-review",
|
|
24272
|
+
"name": "Review pull requests",
|
|
24273
|
+
"description": "Reviews every PR against this repository's conventions and leaves inline comments.",
|
|
24274
|
+
"prompt": "Review this pull request...",
|
|
24275
|
+
"triggers": [
|
|
24276
|
+
{ "type": "github", "config": { "event": "pull_request.opened" } },
|
|
24277
|
+
{ "type": "github", "config": { "event": "pull_request.synchronize" } }
|
|
24278
|
+
]
|
|
24279
|
+
}
|
|
24280
|
+
],
|
|
24281
|
+
"verification": [
|
|
24282
|
+
{ "label": "Installed and built the app", "status": "passed", "detail": "A second install made no changes." },
|
|
24283
|
+
{ "label": "Ran lint, type checks, and unit tests", "status": "passed", "detail": "142 tests passed, matching CI." },
|
|
24284
|
+
{ "label": "Completed a checkout in the browser", "status": "passed", "detail": "Added an item and placed a test order." },
|
|
24285
|
+
{ "label": "Payment webhooks", "status": "skipped", "detail": "Needs a Stripe test key." }
|
|
24286
|
+
],
|
|
24287
|
+
"media": [
|
|
24288
|
+
{ "media_id": "<media-id from replicas media upload>", "title": "Checkout walkthrough" }
|
|
24289
|
+
]
|
|
24290
|
+
}
|
|
24291
|
+
\`\`\`
|
|
24292
|
+
|
|
24293
|
+
When the environment already has automations, their entries look like this:
|
|
24294
|
+
|
|
24295
|
+
\`\`\`json
|
|
24296
|
+
{ "key": "nightly-tests", "action": "keep", "automation_id": "<id from replicas automation list>", "note": "Already runs the full suite on the schedule CI uses." },
|
|
24297
|
+
{ "key": "pr-review", "action": "update", "automation_id": "<id>", "name": "Review pull requests", "description": "...", "prompt": "...", "triggers": [ ... ], "note": "Adds the migration checklist reviewers keep asking for." },
|
|
24298
|
+
{ "key": "docs-sync", "action": "disable", "automation_id": "<id>", "note": "The docs folder it watched was removed in May." }
|
|
24299
|
+
\`\`\`
|
|
24300
|
+
|
|
24301
|
+
Rules:
|
|
24302
|
+
- Omit \`description\`, \`system_prompt\`, \`start_hook\`, or \`warm_hook\` to keep the environment's current value. Set one to \`null\` to remove it when the repository genuinely needs none; explain why in \`summary\` or \`verification\`.
|
|
24303
|
+
- Omit \`environment.name\` unless the current name is misleading.
|
|
24304
|
+
- Every verification row must reflect something you actually ran. Do not list checks you did not run as passed.
|
|
24305
|
+
- A proposal does not change anything. Do not call \`replicas environment edit\`, \`vars set\`, \`files set\`, \`start-hooks save\`, \`warm-hooks save\`, or \`replicas automation create\` during a setup run.
|
|
24306
|
+
- If the user asks for changes after reviewing, revise and run \`propose\` again; the panel shows the latest proposal.
|
|
24307
|
+
|
|
24308
|
+
## 6. Final message
|
|
24309
|
+
|
|
24310
|
+
After \`propose\` succeeds, mark the \`propose\` step completed and send one message with this shape:
|
|
24311
|
+
|
|
24312
|
+
\`\`\`text
|
|
24313
|
+
<Project> is running and ready to review.
|
|
24314
|
+
|
|
24315
|
+
**What I tested**
|
|
24316
|
+
- <outcome in plain words> \u2014 <one-sentence result>
|
|
24317
|
+
- <outcome in plain words> \u2014 <one-sentence result>
|
|
24318
|
+
|
|
24319
|
+
**What I found**
|
|
24320
|
+
- <two to four findings about the codebase that shaped the configuration, written for a person>
|
|
24321
|
+
|
|
24322
|
+

|
|
24323
|
+
[View in Canvas](<View in Replicas URL>)
|
|
24324
|
+
|
|
24325
|
+
**Proposed configuration**
|
|
24326
|
+
Review the start hook, warm hook, system prompt, variables, and automations in the Environment panel on the right. Edit anything inline, then select **Save configuration**. Ask me here if you want changes and I will revise the proposal.
|
|
24327
|
+
\`\`\`
|
|
24328
|
+
|
|
24329
|
+
Keep it under 250 words plus the lists. Do not paste the hooks or system prompt into chat; the panel shows them. Never imply the configuration was saved: saving is the user's action.
|
|
24330
|
+
|
|
24331
|
+
## Safety
|
|
24332
|
+
|
|
24333
|
+
- Never put tokens, passwords, or private keys in hooks, prompts, files, logs, or chat. Values that arrive through \`wait-variables\` are exported to your shell; never echo, cat, or paste them.
|
|
24334
|
+
- Do not weaken network, certificate, or package-integrity settings to make setup pass.
|
|
24335
|
+
- Do not run destructive git operations, force pushes, or anything against production endpoints.
|
|
24336
|
+
- Do not change application code to hide an environment problem. Report it instead.
|
|
24337
|
+
`;
|
|
24338
|
+
var ENVIRONMENT_SETUP_ABILITY = {
|
|
24339
|
+
label: "Environment setup",
|
|
24340
|
+
description: "Explore a codebase, verify it runs, and propose environment hooks, a system prompt, variables, and automations for review.",
|
|
24341
|
+
bullet: "- Setting up, auditing, or improving a Replicas environment for a repository (hooks, system prompt, variables, automations)",
|
|
24342
|
+
section: SECTION3,
|
|
24343
|
+
referenceFile: { name: "ENVIRONMENT-SETUP.md", content: REFERENCE3 }
|
|
24344
|
+
};
|
|
24345
|
+
|
|
23894
24346
|
// ../shared/src/default-skills/replicas-agent/abilities/github.ts
|
|
23895
|
-
var
|
|
24347
|
+
var SECTION4 = `### GitHub
|
|
23896
24348
|
Use the pre-authenticated \`gh\` CLI for repository workflows and the workspace-scoped TypeScript SDK for GitHub API calls.
|
|
23897
24349
|
|
|
23898
24350
|
**Reference:** \`references/GITHUB.md\`
|
|
@@ -23902,7 +24354,7 @@ Use this when:
|
|
|
23902
24354
|
- You need to interact with GitHub issues or actions
|
|
23903
24355
|
- You need to use the GitHub API for advanced operations
|
|
23904
24356
|
- You need to include images in PR descriptions`;
|
|
23905
|
-
var
|
|
24357
|
+
var REFERENCE4 = `# GitHub Integration
|
|
23906
24358
|
|
|
23907
24359
|
This guide covers how to interact with GitHub from within your Replicas workspace. Prefer \`@replicas/sdk\` for API calls so batching and data processing stay in one TypeScript program. The \`gh\` CLI remains useful for ergonomic pull request and git-adjacent workflows.
|
|
23908
24360
|
|
|
@@ -24031,12 +24483,12 @@ var GITHUB_ABILITY = {
|
|
|
24031
24483
|
label: "GitHub",
|
|
24032
24484
|
description: "GitHub workflows through gh and API calls through @replicas/sdk.",
|
|
24033
24485
|
bullet: "- Interacting with GitHub (creating PRs, managing issues, using the API, etc.)",
|
|
24034
|
-
section:
|
|
24035
|
-
referenceFile: { name: "GITHUB.md", content:
|
|
24486
|
+
section: SECTION4,
|
|
24487
|
+
referenceFile: { name: "GITHUB.md", content: REFERENCE4 }
|
|
24036
24488
|
};
|
|
24037
24489
|
|
|
24038
24490
|
// ../shared/src/default-skills/replicas-agent/abilities/gitlab.ts
|
|
24039
|
-
var
|
|
24491
|
+
var SECTION5 = `### GitLab
|
|
24040
24492
|
Use plain git for repository traffic and the workspace-scoped TypeScript SDK for GitLab API operations.
|
|
24041
24493
|
|
|
24042
24494
|
**Reference:** \`references/GITLAB.md\`
|
|
@@ -24045,7 +24497,7 @@ Use this when:
|
|
|
24045
24497
|
- A repository remote is on gitlab.com or a self-managed GitLab instance
|
|
24046
24498
|
- You need to open or update a merge request
|
|
24047
24499
|
- You need GitLab issues, pipelines, comments, or other API data`;
|
|
24048
|
-
var
|
|
24500
|
+
var REFERENCE5 = `# GitLab Integration
|
|
24049
24501
|
|
|
24050
24502
|
Git credentials are preconfigured for fetch, pull, and push. Use \`@replicas/sdk\` for API traffic; never inspect \`~/.git-credentials\`, request a token, or send a credential with curl.
|
|
24051
24503
|
|
|
@@ -24093,12 +24545,12 @@ var GITLAB_ABILITY = {
|
|
|
24093
24545
|
label: "GitLab",
|
|
24094
24546
|
description: "Git for repository traffic and @replicas/sdk for the GitLab API.",
|
|
24095
24547
|
bullet: "- Interacting with GitLab (pushing to GitLab repos, opening merge requests)",
|
|
24096
|
-
section:
|
|
24097
|
-
referenceFile: { name: "GITLAB.md", content:
|
|
24548
|
+
section: SECTION5,
|
|
24549
|
+
referenceFile: { name: "GITLAB.md", content: REFERENCE5 }
|
|
24098
24550
|
};
|
|
24099
24551
|
|
|
24100
24552
|
// ../shared/src/default-skills/replicas-agent/abilities/linear.ts
|
|
24101
|
-
var
|
|
24553
|
+
var SECTION6 = `### Linear
|
|
24102
24554
|
Create tickets, fetch issues, update state, add comments, and search through \`replicas.linear.graphql\` in \`@replicas/sdk\`. This works without a Linear MCP server and refreshes authentication automatically.
|
|
24103
24555
|
|
|
24104
24556
|
**Reference:** \`references/LINEAR.md\`
|
|
@@ -24109,7 +24561,7 @@ Use this when:
|
|
|
24109
24561
|
- You need to update an issue's state or add a comment
|
|
24110
24562
|
- You need to search Linear issues
|
|
24111
24563
|
- A Linear request failed with an authentication error`;
|
|
24112
|
-
var
|
|
24564
|
+
var REFERENCE6 = `# Linear Integration
|
|
24113
24565
|
|
|
24114
24566
|
Use \`@replicas/sdk\`; never request or handle a Linear OAuth token. Replicas refreshes the organization credential behind the gateway.
|
|
24115
24567
|
|
|
@@ -24198,12 +24650,12 @@ var LINEAR_ABILITY = {
|
|
|
24198
24650
|
label: "Linear",
|
|
24199
24651
|
description: "Create tickets, fetch issues, comment, and update state through @replicas/sdk.",
|
|
24200
24652
|
bullet: "- Interacting with Linear (creating tickets, fetching issues, updating state, commenting, or troubleshooting authentication): use replicas.linear.graphql from @replicas/sdk, which refreshes tokens automatically and needs no Linear MCP server. Read references/LINEAR.md before treating a rejected workspace token as a disconnected integration.",
|
|
24201
|
-
section:
|
|
24202
|
-
referenceFile: { name: "LINEAR.md", content:
|
|
24653
|
+
section: SECTION6,
|
|
24654
|
+
referenceFile: { name: "LINEAR.md", content: REFERENCE6 }
|
|
24203
24655
|
};
|
|
24204
24656
|
|
|
24205
24657
|
// ../shared/src/default-skills/replicas-agent/abilities/media.ts
|
|
24206
|
-
var
|
|
24658
|
+
var SECTION7 = `### Media
|
|
24207
24659
|
Deliver screenshots, screen recordings, generated diagrams, audio clips, and self-contained HTML pages to the Replicas dashboard and, when applicable, inline in the destination workflow.
|
|
24208
24660
|
|
|
24209
24661
|
**Reference:** \`references/MEDIA.md\`
|
|
@@ -24214,7 +24666,7 @@ Use this when:
|
|
|
24214
24666
|
- You produce a self-contained HTML report that should be linked from a pull request
|
|
24215
24667
|
- You record video output (browser automation, screen capture) \u2014 including the recommended aspect ratio and FPS
|
|
24216
24668
|
- You need to embed media in a Slack/Linear/GitHub/GitLab message AND keep a referenceable copy in the Replicas dashboard`;
|
|
24217
|
-
var
|
|
24669
|
+
var REFERENCE7 = `# Media (Screenshots, Recordings, Audio, HTML)
|
|
24218
24670
|
|
|
24219
24671
|
This is the single source of truth for delivering screenshots, screen recordings, generated diagrams, audio clips, and self-contained HTML pages through Replicas and external surfaces (Slack, Linear, GitHub, GitLab).
|
|
24220
24672
|
|
|
@@ -24539,8 +24991,8 @@ var MEDIA_ABILITY = {
|
|
|
24539
24991
|
label: "Media",
|
|
24540
24992
|
description: "Deliver media to Replicas and destination workflows with inline uploads.",
|
|
24541
24993
|
bullet: "- Producing or showing the user any media \u2014 screenshots, screen recordings, generated images or diagrams, audio clips, or HTML recap pages \u2014 including in your Replicas chat reply, PR descriptions/comments, and other external platforms",
|
|
24542
|
-
section:
|
|
24543
|
-
referenceFile: { name: "MEDIA.md", content:
|
|
24994
|
+
section: SECTION7,
|
|
24995
|
+
referenceFile: { name: "MEDIA.md", content: REFERENCE7 }
|
|
24544
24996
|
};
|
|
24545
24997
|
|
|
24546
24998
|
// ../shared/src/sandbox.ts
|
|
@@ -24588,7 +25040,7 @@ var memoryGenerationManifestSchema = external_exports.object({
|
|
|
24588
25040
|
});
|
|
24589
25041
|
|
|
24590
25042
|
// ../shared/src/default-skills/replicas-agent/abilities/memory.ts
|
|
24591
|
-
var
|
|
25043
|
+
var SECTION8 = `### Memory
|
|
24592
25044
|
Check relevant long-term memory before substantive work when historical context could improve the result.
|
|
24593
25045
|
|
|
24594
25046
|
**Reference:** \`references/MEMORY.md\`
|
|
@@ -24600,7 +25052,7 @@ Use this when:
|
|
|
24600
25052
|
- Related work may explain an error or implementation choice
|
|
24601
25053
|
|
|
24602
25054
|
When uncertain whether prior context could help, check memory. If you decide something is worth remembering for future sessions, follow the marker guidance in references/MEMORY.md.`;
|
|
24603
|
-
var
|
|
25055
|
+
var REFERENCE8 = `# Long-term memory
|
|
24604
25056
|
|
|
24605
25057
|
Replicas memory is installed under \`~/.replicas/memories\`:
|
|
24606
25058
|
|
|
@@ -24623,13 +25075,13 @@ var MEMORY_ABILITY = {
|
|
|
24623
25075
|
label: "Memory",
|
|
24624
25076
|
description: "Check private and organization memory before substantive work.",
|
|
24625
25077
|
bullet: "",
|
|
24626
|
-
section:
|
|
24627
|
-
referenceFile: { name: "MEMORY.md", content:
|
|
25078
|
+
section: SECTION8,
|
|
25079
|
+
referenceFile: { name: "MEMORY.md", content: REFERENCE8 },
|
|
24628
25080
|
locked: true
|
|
24629
25081
|
};
|
|
24630
25082
|
|
|
24631
25083
|
// ../shared/src/default-skills/replicas-agent/abilities/previews.ts
|
|
24632
|
-
var
|
|
25084
|
+
var SECTION9 = `### Previews
|
|
24633
25085
|
Expose locally running services (web apps, APIs, databases) as public preview URLs so humans can interact with them directly.
|
|
24634
25086
|
|
|
24635
25087
|
**Reference:** \`references/PREVIEWS.md\`
|
|
@@ -24638,7 +25090,7 @@ Use this when:
|
|
|
24638
25090
|
- You need to start a service that a human should view or interact with
|
|
24639
25091
|
- The task involves UI work that benefits from human review
|
|
24640
25092
|
- You are verifying frontend/backend integrations visually`;
|
|
24641
|
-
var
|
|
25093
|
+
var REFERENCE9 = `# Preview URLs
|
|
24642
25094
|
|
|
24643
25095
|
When you run services on ports \u2014 such as a web app, API server, or database \u2014 humans may want to interact with them directly. You can expose your locally running services as public preview URLs.
|
|
24644
25096
|
|
|
@@ -24714,12 +25166,12 @@ var PREVIEWS_ABILITY = {
|
|
|
24714
25166
|
label: "Previews",
|
|
24715
25167
|
description: "Expose locally running services on public preview URLs for humans.",
|
|
24716
25168
|
bullet: "- Creating preview URLs for locally running services",
|
|
24717
|
-
section:
|
|
24718
|
-
referenceFile: { name: "PREVIEWS.md", content:
|
|
25169
|
+
section: SECTION9,
|
|
25170
|
+
referenceFile: { name: "PREVIEWS.md", content: REFERENCE9 }
|
|
24719
25171
|
};
|
|
24720
25172
|
|
|
24721
25173
|
// ../shared/src/default-skills/replicas-agent/abilities/plugins.ts
|
|
24722
|
-
var
|
|
25174
|
+
var SECTION10 = `### Plugins
|
|
24723
25175
|
Discover and execute installed marketplace tools through the workspace-scoped TypeScript SDK.
|
|
24724
25176
|
|
|
24725
25177
|
**Reference:** \`references/PLUGINS.md\`
|
|
@@ -24735,7 +25187,7 @@ Use this when:
|
|
|
24735
25187
|
- The user asks to query or update a connected turbopuffer namespace
|
|
24736
25188
|
- The user asks for PlanetScale organizations, databases, branches, or Insights data
|
|
24737
25189
|
- The user asks to analyze text with Pangram`;
|
|
24738
|
-
var
|
|
25190
|
+
var REFERENCE10 = `# Plugins
|
|
24739
25191
|
|
|
24740
25192
|
Plugins are TypeScript libraries, not MCP servers. Import \`@replicas/sdk\`; Replicas authenticates the workspace and selects the most specific environment the workspace inherits from, then Global. Provider credentials, sessions, and project keys are never exposed.
|
|
24741
25193
|
|
|
@@ -24906,12 +25358,12 @@ var PLUGINS_ABILITY = {
|
|
|
24906
25358
|
label: "Plugins",
|
|
24907
25359
|
description: "Use installed marketplace tools through @replicas/sdk.",
|
|
24908
25360
|
bullet: "- Interacting with installed marketplace plugins through TypeScript",
|
|
24909
|
-
section:
|
|
24910
|
-
referenceFile: { name: "PLUGINS.md", content:
|
|
25361
|
+
section: SECTION10,
|
|
25362
|
+
referenceFile: { name: "PLUGINS.md", content: REFERENCE10 }
|
|
24911
25363
|
};
|
|
24912
25364
|
|
|
24913
25365
|
// ../shared/src/default-skills/replicas-agent/abilities/replicas.ts
|
|
24914
|
-
var
|
|
25366
|
+
var SECTION11 = `### Replicas (in-workspace CLI)
|
|
24915
25367
|
Take action *with* Replicas itself \u2014 manage automations, environments (variables, files), repos, and \`replicas.json\` config \u2014 using the pre-installed, pre-authenticated \`replicas\` CLI.
|
|
24916
25368
|
|
|
24917
25369
|
**Reference:** \`references/REPLICAS.md\`
|
|
@@ -24922,7 +25374,7 @@ Use this when:
|
|
|
24922
25374
|
- The user asks "what envs / repos / automations do I have?"
|
|
24923
25375
|
- The user asks you to scaffold a \`replicas.json\` / \`replicas.yaml\` in a repo
|
|
24924
25376
|
- You need to run a long-lived service (dev server, daemon) \u2014 always use \`replicas service start\` so it survives workspace sleep/wake`;
|
|
24925
|
-
var
|
|
25377
|
+
var REFERENCE11 = `# Replicas (in-workspace CLI)
|
|
24926
25378
|
|
|
24927
25379
|
This guide covers how to take action *with* Replicas itself from inside a Replicas workspace \u2014 managing automations, environments (and their variables/files), repos, previews, and the user's \`replicas.json\` config \u2014 using the pre-installed \`replicas\` CLI.
|
|
24928
25380
|
|
|
@@ -24960,6 +25412,7 @@ In agent mode the CLI hides commands that don't make sense for in-workspace agen
|
|
|
24960
25412
|
| \`replicas repos\` | List repos connected to the org |
|
|
24961
25413
|
| \`replicas environment ...\` | Manage environments, env vars, env files |
|
|
24962
25414
|
| \`replicas automation ...\` | Manage automations (cron + GitHub/GitLab event triggers) |
|
|
25415
|
+
| \`replicas environment-setup ...\` | Report progress and propose configuration during an agent-led environment setup run (covered in \`ENVIRONMENT-SETUP.md\`) |
|
|
24963
25416
|
| \`replicas preview ...\` | Register / list preview URLs (covered in \`PREVIEWS.md\`) |
|
|
24964
25417
|
| \`replicas service ...\` | Run long-lived services detached so they survive workspace sleep/wake (see below) |
|
|
24965
25418
|
| \`replicas media ...\` | Upload, list, share, revoke, or delete workspace media; follow \`MEDIA.md\` for destination embedding |
|
|
@@ -25153,13 +25606,13 @@ var REPLICAS_ABILITY = {
|
|
|
25153
25606
|
description: "Teach the agent about Replicas itself \u2014 automations, environments, the in-workspace CLI.",
|
|
25154
25607
|
// No bullet — help_instructions covers the `replicas` CLI surface in detail.
|
|
25155
25608
|
bullet: "",
|
|
25156
|
-
section:
|
|
25157
|
-
referenceFile: { name: "REPLICAS.md", content:
|
|
25609
|
+
section: SECTION11,
|
|
25610
|
+
referenceFile: { name: "REPLICAS.md", content: REFERENCE11 },
|
|
25158
25611
|
locked: true
|
|
25159
25612
|
};
|
|
25160
25613
|
|
|
25161
25614
|
// ../shared/src/default-skills/replicas-agent/abilities/sentry.ts
|
|
25162
|
-
var
|
|
25615
|
+
var SECTION12 = `### Sentry
|
|
25163
25616
|
Read issues and project data through the workspace-scoped TypeScript SDK.
|
|
25164
25617
|
|
|
25165
25618
|
**Reference:** \`references/SENTRY.md\`
|
|
@@ -25167,7 +25620,7 @@ Read issues and project data through the workspace-scoped TypeScript SDK.
|
|
|
25167
25620
|
Use this when:
|
|
25168
25621
|
- You need to inspect Sentry projects or issues
|
|
25169
25622
|
- A user asks for error-monitoring context outside a webhook-triggered task`;
|
|
25170
|
-
var
|
|
25623
|
+
var REFERENCE12 = `# Sentry Integration
|
|
25171
25624
|
|
|
25172
25625
|
Use \`@replicas/sdk\`; never request or read a Sentry token. Sentry access is organization-scoped and read-only.
|
|
25173
25626
|
|
|
@@ -25185,8 +25638,8 @@ var SENTRY_ABILITY = {
|
|
|
25185
25638
|
label: "Sentry",
|
|
25186
25639
|
description: "Read Sentry projects and issues through @replicas/sdk.",
|
|
25187
25640
|
bullet: "- Interacting with Sentry (reading projects, issues, and error context)",
|
|
25188
|
-
section:
|
|
25189
|
-
referenceFile: { name: "SENTRY.md", content:
|
|
25641
|
+
section: SECTION12,
|
|
25642
|
+
referenceFile: { name: "SENTRY.md", content: REFERENCE12 }
|
|
25190
25643
|
};
|
|
25191
25644
|
|
|
25192
25645
|
// ../shared/src/slack-response-style.ts
|
|
@@ -25196,7 +25649,7 @@ var SLACK_BLOCK_KIT_GUIDANCE = "Use Block Kit whenever structure or a link would
|
|
|
25196
25649
|
var SLACK_PR_BUTTON_GUIDANCE = 'The first time you share a given pull request or merge request link in a thread \u2014 the message announcing you opened it \u2014 attach a button for it: send `blocks` alongside `text` \u2014 a `section` block holding your message as `mrkdwn`, then an `actions` block with one element per newly shared link, `{"type": "button", "style": "primary", "text": {"type": "plain_text", "text": "View PR"}, "url": "<pr url>", "action_id": "view_pr"}`. Later messages about a pull request you already linked in this thread keep the link in the sentence and get no button, and never re-post a button for a link someone already has. Label it "View MR" for GitLab, and if there are several give each button a unique `action_id` and name its repository in the label ("View PR \xB7 web"). Always keep `text` populated with the same message \u2014 Slack uses it for notifications and fallback \u2014 and keep the link in the sentence too.';
|
|
25197
25650
|
|
|
25198
25651
|
// ../shared/src/default-skills/replicas-agent/abilities/slack.ts
|
|
25199
|
-
var
|
|
25652
|
+
var SECTION13 = `### Slack
|
|
25200
25653
|
Send messages, read threads, search conversations, and transfer files through the workspace-scoped TypeScript SDK.
|
|
25201
25654
|
|
|
25202
25655
|
**Reference:** \`references/SLACK.md\`
|
|
@@ -25206,7 +25659,7 @@ Use this when:
|
|
|
25206
25659
|
- You need to read or search Slack conversations
|
|
25207
25660
|
- You need to download a file attached to a Slack message
|
|
25208
25661
|
- You encounter a Slack message link and need its full thread`;
|
|
25209
|
-
var
|
|
25662
|
+
var REFERENCE13 = `# Slack Integration
|
|
25210
25663
|
|
|
25211
25664
|
Use \`@replicas/sdk\`; never read or send a Slack token directly. The SDK calls Replicas, which selects only this workspace's organization connection.
|
|
25212
25665
|
|
|
@@ -25284,8 +25737,8 @@ var SLACK_ABILITY = {
|
|
|
25284
25737
|
label: "Slack",
|
|
25285
25738
|
description: "Send messages, read threads, search, and transfer files through @replicas/sdk.",
|
|
25286
25739
|
bullet: "- Interacting with Slack (listing channels, sending messages, reading threads, or searching): use replicas.slack.call from @replicas/sdk. Read references/SLACK.md; no Slack MCP server or provider token in the VM is required.",
|
|
25287
|
-
section:
|
|
25288
|
-
referenceFile: { name: "SLACK.md", content:
|
|
25740
|
+
section: SECTION13,
|
|
25741
|
+
referenceFile: { name: "SLACK.md", content: REFERENCE13 }
|
|
25289
25742
|
};
|
|
25290
25743
|
|
|
25291
25744
|
// ../shared/src/default-skills/replicas-agent/registry.ts
|
|
@@ -25294,6 +25747,7 @@ var REPLICAS_AGENT_ABILITY_REGISTRY = {
|
|
|
25294
25747
|
memory: MEMORY_ABILITY,
|
|
25295
25748
|
computer: COMPUTER_ABILITY,
|
|
25296
25749
|
docker: DOCKER_ABILITY,
|
|
25750
|
+
environment_setup: ENVIRONMENT_SETUP_ABILITY,
|
|
25297
25751
|
github: GITHUB_ABILITY,
|
|
25298
25752
|
gitlab: GITLAB_ABILITY,
|
|
25299
25753
|
linear: LINEAR_ABILITY,
|
|
@@ -26260,7 +26714,7 @@ function parseOpencodeEvents(events) {
|
|
|
26260
26714
|
upsertDisplayMessage(messages, {
|
|
26261
26715
|
id,
|
|
26262
26716
|
type: "file_change",
|
|
26263
|
-
changes: files.map((
|
|
26717
|
+
changes: files.map((path7) => ({ path: path7, kind: "update" })),
|
|
26264
26718
|
status: "completed",
|
|
26265
26719
|
timestamp
|
|
26266
26720
|
});
|
|
@@ -27365,6 +27819,75 @@ var EGRESS_WORKSPACE_SHELL_VARS = {
|
|
|
27365
27819
|
EGRESS_EXIT_IP_ENDPOINTS: EGRESS_EXIT_IP_ENDPOINTS.join(" ")
|
|
27366
27820
|
};
|
|
27367
27821
|
|
|
27822
|
+
// ../shared/src/runtime-env.ts
|
|
27823
|
+
function shellQuotePosix(value) {
|
|
27824
|
+
return `'${value.split("'").join("'\\''")}'`;
|
|
27825
|
+
}
|
|
27826
|
+
function serializePosixEnvFile(env, unsetKeys = []) {
|
|
27827
|
+
return `${[
|
|
27828
|
+
...[...unsetKeys].map((key) => `unset ${key}`),
|
|
27829
|
+
...Object.entries(env).filter(([, value]) => value.length > 0).map(([key, value]) => `export ${key}=${shellQuotePosix(value)}`)
|
|
27830
|
+
].join("\n")}
|
|
27831
|
+
`;
|
|
27832
|
+
}
|
|
27833
|
+
function parsePosixEnvUnsetKeys(content) {
|
|
27834
|
+
return content.split("\n").filter((line) => line.startsWith("unset ")).map((line) => line.slice("unset ".length).trim());
|
|
27835
|
+
}
|
|
27836
|
+
function parsePosixEnvFile(content) {
|
|
27837
|
+
const result = {};
|
|
27838
|
+
let pos = 0;
|
|
27839
|
+
while (pos < content.length) {
|
|
27840
|
+
let lineStart;
|
|
27841
|
+
if (pos === 0 || content[pos - 1] === "\n") {
|
|
27842
|
+
lineStart = pos;
|
|
27843
|
+
} else {
|
|
27844
|
+
const nl2 = content.indexOf("\n", pos);
|
|
27845
|
+
if (nl2 === -1) break;
|
|
27846
|
+
lineStart = nl2 + 1;
|
|
27847
|
+
}
|
|
27848
|
+
if (!content.startsWith("export ", lineStart)) {
|
|
27849
|
+
const nl2 = content.indexOf("\n", lineStart);
|
|
27850
|
+
if (nl2 === -1) break;
|
|
27851
|
+
pos = nl2 + 1;
|
|
27852
|
+
continue;
|
|
27853
|
+
}
|
|
27854
|
+
const nameStart = lineStart + "export ".length;
|
|
27855
|
+
const eqIdx = content.indexOf("=", nameStart);
|
|
27856
|
+
if (eqIdx === -1) break;
|
|
27857
|
+
const name = content.slice(nameStart, eqIdx).trim();
|
|
27858
|
+
let cursor = eqIdx + 1;
|
|
27859
|
+
if (content[cursor] !== "'") {
|
|
27860
|
+
const nl2 = content.indexOf("\n", cursor);
|
|
27861
|
+
pos = nl2 === -1 ? content.length : nl2 + 1;
|
|
27862
|
+
continue;
|
|
27863
|
+
}
|
|
27864
|
+
cursor += 1;
|
|
27865
|
+
let value = "";
|
|
27866
|
+
let closed = false;
|
|
27867
|
+
while (cursor < content.length) {
|
|
27868
|
+
const ch = content[cursor];
|
|
27869
|
+
if (ch === "'") {
|
|
27870
|
+
if (content.startsWith("\\''", cursor + 1)) {
|
|
27871
|
+
value += "'";
|
|
27872
|
+
cursor += 4;
|
|
27873
|
+
continue;
|
|
27874
|
+
}
|
|
27875
|
+
cursor += 1;
|
|
27876
|
+
closed = true;
|
|
27877
|
+
break;
|
|
27878
|
+
}
|
|
27879
|
+
value += ch;
|
|
27880
|
+
cursor += 1;
|
|
27881
|
+
}
|
|
27882
|
+
if (closed && name) {
|
|
27883
|
+
result[name] = value;
|
|
27884
|
+
}
|
|
27885
|
+
const nl = content.indexOf("\n", cursor);
|
|
27886
|
+
pos = nl === -1 ? content.length : nl + 1;
|
|
27887
|
+
}
|
|
27888
|
+
return result;
|
|
27889
|
+
}
|
|
27890
|
+
|
|
27368
27891
|
// ../shared/src/slash-commands.ts
|
|
27369
27892
|
var SIDE_CHAT_COMMANDS = ["/btw", "/side"];
|
|
27370
27893
|
var SLASH_COMMANDS = [
|
|
@@ -27416,9 +27939,6 @@ var HOOK_EXEC_MAX_BUFFER_BYTES = 10 * 1024 * 1024;
|
|
|
27416
27939
|
// ../shared/src/replicas-config.ts
|
|
27417
27940
|
var REPLICAS_CONFIG_FILENAMES = ["replicas.json", "replicas.yaml", "replicas.yml"];
|
|
27418
27941
|
|
|
27419
|
-
// ../shared/src/uuid.ts
|
|
27420
|
-
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
27421
|
-
|
|
27422
27942
|
// ../shared/src/terminal.ts
|
|
27423
27943
|
var CONTROL_CHARACTERS = /[\u0000-\u001F\u007F-\u009F]/g;
|
|
27424
27944
|
function sanitizeTerminalLine(value) {
|
|
@@ -27479,7 +27999,7 @@ var headlessFilesystemAgentResultSchema = external_exports.object({
|
|
|
27479
27999
|
});
|
|
27480
28000
|
|
|
27481
28001
|
// ../shared/src/cli-version.ts
|
|
27482
|
-
var CLI_VERSION = "0.2.
|
|
28002
|
+
var CLI_VERSION = "0.2.753";
|
|
27483
28003
|
|
|
27484
28004
|
// ../shared/src/version.ts
|
|
27485
28005
|
function compareVersions(v1, v2) {
|
|
@@ -28215,186 +28735,6 @@ function identityTokenUrl() {
|
|
|
28215
28735
|
return `http://127.0.0.1:${IDENTITY_PROXY_PORT}${IDENTITY_TOKEN_PATH}`;
|
|
28216
28736
|
}
|
|
28217
28737
|
|
|
28218
|
-
// ../shared/src/routes/environment-setups.ts
|
|
28219
|
-
var ENVIRONMENT_SETUP_STEPS = [
|
|
28220
|
-
{ key: "understand", label: "Understand the codebase" },
|
|
28221
|
-
{ key: "install", label: "Install dependencies and run the app" },
|
|
28222
|
-
{ key: "verify", label: "Verify checks and record a walkthrough" },
|
|
28223
|
-
{ key: "configure", label: "Draft hooks, system prompt, and automations" },
|
|
28224
|
-
{ key: "propose", label: "Propose the configuration for review" }
|
|
28225
|
-
];
|
|
28226
|
-
var ENVIRONMENT_SETUP_STEP_STATUSES = ["pending", "in_progress", "completed", "skipped"];
|
|
28227
|
-
var ENVIRONMENT_SETUP_RUN_STATUSES = ["running", "proposed", "applied", "failed", "cancelled"];
|
|
28228
|
-
var ENVIRONMENT_SETUP_AUTOMATION_ACTIONS = ["create", "update", "keep", "disable"];
|
|
28229
|
-
var ENVIRONMENT_SETUP_VERIFICATION_STATUSES = ["passed", "failed", "skipped"];
|
|
28230
|
-
var ENVIRONMENT_SETUP_LIMITS = {
|
|
28231
|
-
summaryChars: 600,
|
|
28232
|
-
stackItems: 30,
|
|
28233
|
-
nameChars: 120,
|
|
28234
|
-
descriptionChars: 1e3,
|
|
28235
|
-
systemPromptChars: 2e4,
|
|
28236
|
-
hookChars: 5e4,
|
|
28237
|
-
variables: 50,
|
|
28238
|
-
variableKeyChars: 128,
|
|
28239
|
-
variableDescriptionChars: 500,
|
|
28240
|
-
automations: 8,
|
|
28241
|
-
automationKeyChars: 80,
|
|
28242
|
-
automationPromptChars: 1e4,
|
|
28243
|
-
automationTriggers: 5,
|
|
28244
|
-
automationNoteChars: 300,
|
|
28245
|
-
verificationItems: 8,
|
|
28246
|
-
verificationDetailChars: 300,
|
|
28247
|
-
mediaItems: 8,
|
|
28248
|
-
repositories: 20
|
|
28249
|
-
};
|
|
28250
|
-
var ENVIRONMENT_SETUP_VARIABLE_WAIT = { defaultMs: 5 * 6e4, maxMs: 15 * 6e4, pollMs: 5e3 };
|
|
28251
|
-
var VARIABLE_KEY_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
28252
|
-
var text = (max) => max === void 0 ? external_exports.string().trim() : external_exports.string().trim().max(max);
|
|
28253
|
-
var requiredText = (max) => text(max).min(1, "must not be empty");
|
|
28254
|
-
var optionalText = (max) => text(max).nullish().transform((value) => value || null);
|
|
28255
|
-
var clearableText = (max) => text(max).nullish().transform((value) => value === void 0 ? void 0 : value || null);
|
|
28256
|
-
var list = (item, max) => max === void 0 ? external_exports.array(item) : external_exports.array(item).max(max);
|
|
28257
|
-
var ENVIRONMENT_SETUP_AUTHORED_TRIGGER_TYPES = ["cron", "github", "gitlab"];
|
|
28258
|
-
function isEnvironmentSetupAuthoredTriggerType(type) {
|
|
28259
|
-
return ENVIRONMENT_SETUP_AUTHORED_TRIGGER_TYPES.some((authored) => authored === type);
|
|
28260
|
-
}
|
|
28261
|
-
var repositoryTriggerConfigSchema = external_exports.object({
|
|
28262
|
-
event: external_exports.string(),
|
|
28263
|
-
repository_ids: external_exports.array(external_exports.string().regex(UUID_RE, "must be a repository id")).optional(),
|
|
28264
|
-
group_pr_events: external_exports.boolean().optional(),
|
|
28265
|
-
excluded_actors: external_exports.array(external_exports.string()).optional()
|
|
28266
|
-
});
|
|
28267
|
-
var proposalTriggerSchema = external_exports.discriminatedUnion("type", [
|
|
28268
|
-
external_exports.object({ type: external_exports.literal("cron"), config: external_exports.object({ schedule: external_exports.string(), timezone: external_exports.string().optional() }) }),
|
|
28269
|
-
external_exports.object({ type: external_exports.literal("github"), config: repositoryTriggerConfigSchema }),
|
|
28270
|
-
external_exports.object({ type: external_exports.literal("gitlab"), config: repositoryTriggerConfigSchema })
|
|
28271
|
-
]);
|
|
28272
|
-
var existingTriggerSchema = external_exports.custom(
|
|
28273
|
-
(value) => isRecord(value) && typeof value.type === "string" && isRecord(value.config),
|
|
28274
|
-
"must be an automation trigger"
|
|
28275
|
-
);
|
|
28276
|
-
var carriedTriggerSchema = existingTriggerSchema.refine(
|
|
28277
|
-
(trigger) => !isEnvironmentSetupAuthoredTriggerType(trigger.type)
|
|
28278
|
-
);
|
|
28279
|
-
function automationSchema(limits) {
|
|
28280
|
-
const authored = external_exports.object({
|
|
28281
|
-
name: text(limits.nameChars),
|
|
28282
|
-
description: text(limits.descriptionChars),
|
|
28283
|
-
prompt: text(limits.automationPromptChars),
|
|
28284
|
-
triggers: list(proposalTriggerSchema, limits.automationTriggers)
|
|
28285
|
-
});
|
|
28286
|
-
const updated = authored.extend({ triggers: list(external_exports.union([proposalTriggerSchema, carriedTriggerSchema]), limits.automationTriggers) });
|
|
28287
|
-
return external_exports.object({
|
|
28288
|
-
key: requiredText(limits.automationKeyChars),
|
|
28289
|
-
action: external_exports.enum(ENVIRONMENT_SETUP_AUTOMATION_ACTIONS).default("create"),
|
|
28290
|
-
automation_id: external_exports.string().regex(UUID_RE, "must be an automation id").nullable().default(null),
|
|
28291
|
-
name: text().default(""),
|
|
28292
|
-
description: optionalText().transform((value) => value ?? ""),
|
|
28293
|
-
prompt: text().default(""),
|
|
28294
|
-
triggers: list(existingTriggerSchema).default([]),
|
|
28295
|
-
note: optionalText(limits.automationNoteChars)
|
|
28296
|
-
}).superRefine((automation2, ctx) => {
|
|
28297
|
-
if (automation2.action === "create" && automation2.automation_id) {
|
|
28298
|
-
ctx.addIssue({ code: "custom", path: ["automation_id"], message: "belongs on an update, keep, or disable entry" });
|
|
28299
|
-
}
|
|
28300
|
-
if (automation2.action !== "create" && !automation2.automation_id) {
|
|
28301
|
-
ctx.addIssue({ code: "custom", path: ["automation_id"], message: "must be the id of an automation attached to this environment" });
|
|
28302
|
-
}
|
|
28303
|
-
if (automation2.action === "create" || automation2.action === "update") {
|
|
28304
|
-
if (!automation2.name) ctx.addIssue({ code: "custom", path: ["name"], message: "must not be empty" });
|
|
28305
|
-
if (!automation2.prompt) ctx.addIssue({ code: "custom", path: ["prompt"], message: "must not be empty" });
|
|
28306
|
-
if (automation2.triggers.length === 0) ctx.addIssue({ code: "custom", path: ["triggers"], message: "must not be empty" });
|
|
28307
|
-
}
|
|
28308
|
-
}).transform((automation2, ctx) => {
|
|
28309
|
-
if (automation2.action === "keep" || automation2.action === "disable") return automation2;
|
|
28310
|
-
const content = (automation2.action === "update" ? updated : authored).safeParse(automation2);
|
|
28311
|
-
if (content.success) return { ...automation2, ...content.data };
|
|
28312
|
-
for (const issue2 of content.error.issues) ctx.addIssue({ ...issue2, code: "custom" });
|
|
28313
|
-
return external_exports.NEVER;
|
|
28314
|
-
});
|
|
28315
|
-
}
|
|
28316
|
-
function automationListSchema(limits) {
|
|
28317
|
-
return list(automationSchema(limits)).default([]).superRefine((automations, ctx) => {
|
|
28318
|
-
if (new Set(automations.map((automation2) => automation2.key)).size !== automations.length) {
|
|
28319
|
-
ctx.addIssue({ code: "custom", message: "must have unique keys" });
|
|
28320
|
-
}
|
|
28321
|
-
const targets = automations.flatMap((automation2) => automation2.automation_id ?? []);
|
|
28322
|
-
if (new Set(targets).size !== targets.length) {
|
|
28323
|
-
ctx.addIssue({ code: "custom", message: "must mention each existing automation once" });
|
|
28324
|
-
}
|
|
28325
|
-
if (limits.automations !== void 0 && automations.filter((automation2) => automation2.action === "create").length > limits.automations) {
|
|
28326
|
-
ctx.addIssue({ code: "custom", message: `must create at most ${limits.automations} new automations` });
|
|
28327
|
-
}
|
|
28328
|
-
});
|
|
28329
|
-
}
|
|
28330
|
-
function environmentSchema(limits) {
|
|
28331
|
-
return external_exports.object({
|
|
28332
|
-
name: optionalText(limits.nameChars).transform((value) => value ?? void 0),
|
|
28333
|
-
description: clearableText(limits.descriptionChars),
|
|
28334
|
-
system_prompt: clearableText(limits.systemPromptChars),
|
|
28335
|
-
start_hook: clearableText(limits.hookChars),
|
|
28336
|
-
warm_hook: clearableText(limits.hookChars)
|
|
28337
|
-
});
|
|
28338
|
-
}
|
|
28339
|
-
function variableSchema(limits, requiredDefault) {
|
|
28340
|
-
return external_exports.object({
|
|
28341
|
-
key: external_exports.string().regex(VARIABLE_KEY_RE, "must be a valid environment variable name").max(limits.variableKeyChars ?? Number.POSITIVE_INFINITY),
|
|
28342
|
-
description: optionalText(limits.variableDescriptionChars).transform((value) => value ?? ""),
|
|
28343
|
-
required: external_exports.boolean().default(requiredDefault)
|
|
28344
|
-
});
|
|
28345
|
-
}
|
|
28346
|
-
function proposalSchema(limits) {
|
|
28347
|
-
return external_exports.object({
|
|
28348
|
-
summary: requiredText(limits.summaryChars),
|
|
28349
|
-
stack: list(text(), limits.stackItems).default([]).transform((items) => items.filter(Boolean)),
|
|
28350
|
-
environment: environmentSchema(limits),
|
|
28351
|
-
variables: list(variableSchema(limits, false), limits.variables).default([]),
|
|
28352
|
-
automations: automationListSchema(limits),
|
|
28353
|
-
verification: list(external_exports.object({
|
|
28354
|
-
label: requiredText(limits.nameChars),
|
|
28355
|
-
status: external_exports.enum(ENVIRONMENT_SETUP_VERIFICATION_STATUSES),
|
|
28356
|
-
detail: optionalText(limits.verificationDetailChars).transform((value) => value ?? void 0)
|
|
28357
|
-
}), limits.verificationItems).default([]),
|
|
28358
|
-
media: list(external_exports.object({
|
|
28359
|
-
media_id: external_exports.string().regex(UUID_RE, "must be a media id"),
|
|
28360
|
-
title: requiredText(limits.nameChars)
|
|
28361
|
-
}), limits.mediaItems).default([])
|
|
28362
|
-
});
|
|
28363
|
-
}
|
|
28364
|
-
var environmentSetupProposalSchema = proposalSchema({});
|
|
28365
|
-
var environmentSetupProposalSubmissionSchema = proposalSchema(ENVIRONMENT_SETUP_LIMITS);
|
|
28366
|
-
var environmentSetupVariableRequestSchema = variableSchema({}, false).extend({
|
|
28367
|
-
status: external_exports.enum(["pending", "provided", "skipped"]),
|
|
28368
|
-
requested_at: external_exports.string(),
|
|
28369
|
-
resolved_at: external_exports.string().nullable().default(null)
|
|
28370
|
-
});
|
|
28371
|
-
var environmentSetupRunStateSchema = external_exports.object({
|
|
28372
|
-
status: external_exports.enum(ENVIRONMENT_SETUP_RUN_STATUSES),
|
|
28373
|
-
steps: external_exports.partialRecord(external_exports.enum(ENVIRONMENT_SETUP_STEPS.map((step) => step.key)), external_exports.enum(ENVIRONMENT_SETUP_STEP_STATUSES)).default({}),
|
|
28374
|
-
proposal: environmentSetupProposalSchema.nullable().default(null),
|
|
28375
|
-
applied: external_exports.object({
|
|
28376
|
-
applied_at: external_exports.string(),
|
|
28377
|
-
automation_ids: external_exports.array(external_exports.string())
|
|
28378
|
-
}).nullable().default(null),
|
|
28379
|
-
variable_requests: external_exports.array(environmentSetupVariableRequestSchema).default([])
|
|
28380
|
-
});
|
|
28381
|
-
var applyEnvironmentSetupRequestSchema = external_exports.object({
|
|
28382
|
-
environment: environmentSchema(ENVIRONMENT_SETUP_LIMITS).extend({ name: requiredText(ENVIRONMENT_SETUP_LIMITS.nameChars) }),
|
|
28383
|
-
variables: list(external_exports.object({ key: external_exports.string().regex(VARIABLE_KEY_RE), value: external_exports.string() }), ENVIRONMENT_SETUP_LIMITS.variables).default([]).refine((variables) => new Set(variables.map((variable) => variable.key)).size === variables.length, "must have unique keys").transform((variables) => variables.filter((variable) => variable.value.length > 0)),
|
|
28384
|
-
automations: automationListSchema(ENVIRONMENT_SETUP_LIMITS)
|
|
28385
|
-
});
|
|
28386
|
-
var requestEnvironmentSetupVariablesSchema = external_exports.object({
|
|
28387
|
-
variables: list(variableSchema(ENVIRONMENT_SETUP_LIMITS, true), ENVIRONMENT_SETUP_LIMITS.variables).min(1, "must not be empty")
|
|
28388
|
-
}).superRefine(({ variables }, ctx) => {
|
|
28389
|
-
if (new Set(variables.map((variable) => variable.key)).size !== variables.length) {
|
|
28390
|
-
ctx.addIssue({ code: "custom", path: ["variables"], message: "must have unique keys" });
|
|
28391
|
-
}
|
|
28392
|
-
});
|
|
28393
|
-
var respondEnvironmentSetupVariablesSchema = external_exports.object({
|
|
28394
|
-
values: external_exports.record(external_exports.string().regex(VARIABLE_KEY_RE), external_exports.string()).default({}),
|
|
28395
|
-
skipped: external_exports.array(external_exports.string().regex(VARIABLE_KEY_RE)).default([])
|
|
28396
|
-
});
|
|
28397
|
-
|
|
28398
28738
|
// src/lib/monolith-url.ts
|
|
28399
28739
|
var MONOLITH_URL = process.env.REPLICAS_MONOLITH_URL || process.env.MONOLITH_URL || "https://api.replicas.dev";
|
|
28400
28740
|
|
|
@@ -29569,7 +29909,7 @@ async function configListCommand() {
|
|
|
29569
29909
|
var import_http2 = __toESM(require("http"));
|
|
29570
29910
|
var import_url4 = require("url");
|
|
29571
29911
|
|
|
29572
|
-
// src/
|
|
29912
|
+
// ../shared/src/pkce.ts
|
|
29573
29913
|
var import_crypto = require("crypto");
|
|
29574
29914
|
function generatePkceCodes() {
|
|
29575
29915
|
const verifierBytes = (0, import_crypto.randomBytes)(32);
|
|
@@ -29974,8 +30314,8 @@ async function claudeAuthCommand(options = {}) {
|
|
|
29974
30314
|
var CLIENT_ID = "1031625952748946";
|
|
29975
30315
|
var AUTH_URL = "https://auth.meta.com";
|
|
29976
30316
|
var API_KEY_URL = "https://api.meta.ai/muse-code/key";
|
|
29977
|
-
async function post(
|
|
29978
|
-
return fetch(`${AUTH_URL}${
|
|
30317
|
+
async function post(path7, body) {
|
|
30318
|
+
return fetch(`${AUTH_URL}${path7}`, {
|
|
29979
30319
|
method: "POST",
|
|
29980
30320
|
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
29981
30321
|
body
|
|
@@ -30650,14 +30990,163 @@ Repositories (${response.repositories.length}):
|
|
|
30650
30990
|
}
|
|
30651
30991
|
}
|
|
30652
30992
|
|
|
30653
|
-
// src/commands/
|
|
30993
|
+
// src/commands/environment-setup.ts
|
|
30994
|
+
var import_fs4 = __toESM(require("fs"));
|
|
30995
|
+
var import_os3 = __toESM(require("os"));
|
|
30996
|
+
var import_path5 = __toESM(require("path"));
|
|
30654
30997
|
var import_chalk19 = __toESM(require("chalk"));
|
|
30998
|
+
var STEP_KEYS = ENVIRONMENT_SETUP_STEPS.map((step) => step.key).join(", ");
|
|
30999
|
+
async function fetchCurrentRun() {
|
|
31000
|
+
ensureOrgApiAuthenticated();
|
|
31001
|
+
if (!isEnvironmentSetupWorkspace()) {
|
|
31002
|
+
throw new Error("environment-setup commands run inside a Replicas setup workspace");
|
|
31003
|
+
}
|
|
31004
|
+
return orgAuthenticatedFetch("/v1/environment-setups/current");
|
|
31005
|
+
}
|
|
31006
|
+
async function environmentSetupStatusCommand() {
|
|
31007
|
+
const { run, environment: environment2, repositories } = await fetchCurrentRun();
|
|
31008
|
+
console.log(import_chalk19.default.bold(`
|
|
31009
|
+
Environment setup: ${environment2.name}
|
|
31010
|
+
`));
|
|
31011
|
+
console.log(` Run: ${run.id}`);
|
|
31012
|
+
console.log(` Status: ${run.status}${run.error ? import_chalk19.default.red(` (${run.error})`) : ""}`);
|
|
31013
|
+
console.log(` Environment: ${environment2.id}`);
|
|
31014
|
+
console.log(` Repositories: ${repositories.map((repo) => `${repo.name} (${repo.default_branch})`).join(", ") || "none"}`);
|
|
31015
|
+
console.log("\n Steps:");
|
|
31016
|
+
for (const step of ENVIRONMENT_SETUP_STEPS) {
|
|
31017
|
+
const status = run.steps[step.key] ?? "pending";
|
|
31018
|
+
const marker = status === "completed" ? import_chalk19.default.green("\u2713") : status === "in_progress" ? import_chalk19.default.cyan("\u25B8") : status === "skipped" ? import_chalk19.default.gray("\u2013") : import_chalk19.default.gray("\u25CB");
|
|
31019
|
+
console.log(` ${marker} ${step.key.padEnd(11)} ${import_chalk19.default.gray(step.label)} ${import_chalk19.default.gray(`[${status}]`)}`);
|
|
31020
|
+
}
|
|
31021
|
+
if (run.variable_requests.length > 0) {
|
|
31022
|
+
console.log("\n Variables:");
|
|
31023
|
+
printVariableRequests(run.variable_requests);
|
|
31024
|
+
}
|
|
31025
|
+
console.log(run.proposal ? import_chalk19.default.gray("\n A proposal has been submitted. Run `propose` again to replace it.\n") : import_chalk19.default.gray("\n No proposal yet. Submit one with `replicas environment-setup propose --file <path>`.\n"));
|
|
31026
|
+
}
|
|
31027
|
+
async function environmentSetupStepCommand(key, status) {
|
|
31028
|
+
if (!isEnvironmentSetupStepKey(key)) {
|
|
31029
|
+
throw new Error(`Unknown step "${key}". Use one of: ${STEP_KEYS}`);
|
|
31030
|
+
}
|
|
31031
|
+
if (!isEnvironmentSetupStepStatus(status)) {
|
|
31032
|
+
throw new Error(`Unknown status "${status}". Use one of: ${ENVIRONMENT_SETUP_STEP_STATUSES.join(", ")}`);
|
|
31033
|
+
}
|
|
31034
|
+
const { run } = await fetchCurrentRun();
|
|
31035
|
+
const body = { steps: { [key]: status } };
|
|
31036
|
+
await orgAuthenticatedFetch(`/v1/environment-setups/${run.id}/steps`, {
|
|
31037
|
+
method: "POST",
|
|
31038
|
+
body
|
|
31039
|
+
});
|
|
31040
|
+
console.log(import_chalk19.default.green(`
|
|
31041
|
+
\u2713 ${key} \u2192 ${status}
|
|
31042
|
+
`));
|
|
31043
|
+
}
|
|
31044
|
+
function readJsonFile(file2, label) {
|
|
31045
|
+
try {
|
|
31046
|
+
return JSON.parse(import_fs4.default.readFileSync(file2, "utf8"));
|
|
31047
|
+
} catch (error51) {
|
|
31048
|
+
throw new Error(`Could not read ${label} JSON from ${file2}: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
31049
|
+
}
|
|
31050
|
+
}
|
|
31051
|
+
async function environmentSetupProposeCommand(options) {
|
|
31052
|
+
const proposal = readJsonFile(options.file, "proposal");
|
|
31053
|
+
const { run } = await fetchCurrentRun();
|
|
31054
|
+
const result = await orgAuthenticatedFetch(`/v1/environment-setups/${run.id}/proposal`, {
|
|
31055
|
+
method: "POST",
|
|
31056
|
+
body: { proposal }
|
|
31057
|
+
});
|
|
31058
|
+
const submitted = result.run.proposal;
|
|
31059
|
+
console.log(import_chalk19.default.green("\n\u2713 Proposal submitted.\n"));
|
|
31060
|
+
if (submitted) {
|
|
31061
|
+
console.log(` Automations: ${submitted.automations.length}`);
|
|
31062
|
+
console.log(` Variables: ${submitted.variables.length}`);
|
|
31063
|
+
console.log(` Checks: ${submitted.verification.length}`);
|
|
31064
|
+
console.log(` Media: ${submitted.media.length}`);
|
|
31065
|
+
}
|
|
31066
|
+
console.log(import_chalk19.default.gray("\n The user reviews and saves it from the Environment panel; nothing has been applied yet.\n"));
|
|
31067
|
+
}
|
|
31068
|
+
var RUNTIME_ENV_FILE = import_path5.default.join(import_os3.default.homedir(), ".replicas", "runtime-env.sh");
|
|
31069
|
+
var EXPORTED_KEYS_FILE = import_path5.default.join(import_os3.default.homedir(), ".replicas", "environment-setup-exported-keys.json");
|
|
31070
|
+
function printVariableRequests(requests) {
|
|
31071
|
+
for (const request of requests) {
|
|
31072
|
+
const marker = request.status === "provided" ? import_chalk19.default.green("\u2713") : request.status === "skipped" ? import_chalk19.default.gray("\u2013") : import_chalk19.default.cyan("\u2026");
|
|
31073
|
+
console.log(` ${marker} ${request.key.padEnd(32)} ${import_chalk19.default.gray(`[${request.status}${request.required ? ", required" : ""}]`)}`);
|
|
31074
|
+
}
|
|
31075
|
+
}
|
|
31076
|
+
async function environmentSetupRequestVariablesCommand(options) {
|
|
31077
|
+
const request = readJsonFile(options.file, "variable request");
|
|
31078
|
+
const { run } = await fetchCurrentRun();
|
|
31079
|
+
const result = await orgAuthenticatedFetch(`/v1/environment-setups/${run.id}/variable-requests`, {
|
|
31080
|
+
method: "POST",
|
|
31081
|
+
body: request
|
|
31082
|
+
});
|
|
31083
|
+
console.log(import_chalk19.default.green("\n\u2713 Variables requested.\n"));
|
|
31084
|
+
printVariableRequests(result.run.variable_requests);
|
|
31085
|
+
console.log(import_chalk19.default.gray("\n The user sees this in the Environment panel. Keep working and run `replicas environment-setup wait-variables` when you need a value.\n"));
|
|
31086
|
+
}
|
|
31087
|
+
function parseWaitTimeoutMs(raw) {
|
|
31088
|
+
if (!raw) return ENVIRONMENT_SETUP_VARIABLE_WAIT.defaultMs;
|
|
31089
|
+
const match = /^(\d+)(s|m)?$/.exec(raw.trim());
|
|
31090
|
+
if (!match) throw new Error(`Invalid timeout "${raw}". Use seconds or minutes, for example 90s or 5m`);
|
|
31091
|
+
const ms = Number(match[1]) * (match[2] === "m" ? 6e4 : 1e3);
|
|
31092
|
+
return Math.min(Math.max(ms, ENVIRONMENT_SETUP_VARIABLE_WAIT.pollMs), ENVIRONMENT_SETUP_VARIABLE_WAIT.maxMs);
|
|
31093
|
+
}
|
|
31094
|
+
function exportToRuntimeEnv(variables) {
|
|
31095
|
+
import_fs4.default.mkdirSync(import_path5.default.dirname(RUNTIME_ENV_FILE), { recursive: true });
|
|
31096
|
+
const existing = import_fs4.default.existsSync(RUNTIME_ENV_FILE) ? import_fs4.default.readFileSync(RUNTIME_ENV_FILE, "utf8") : "";
|
|
31097
|
+
const exportedKeys = import_fs4.default.existsSync(EXPORTED_KEYS_FILE) ? JSON.parse(import_fs4.default.readFileSync(EXPORTED_KEYS_FILE, "utf8")) : [];
|
|
31098
|
+
const owned = new Set(Array.isArray(exportedKeys) ? exportedKeys.filter(isNonEmptyString) : []);
|
|
31099
|
+
const env = parsePosixEnvFile(existing);
|
|
31100
|
+
for (const key of owned) delete env[key];
|
|
31101
|
+
const exported = variables.filter((variable) => !variable.key.startsWith("REPLICAS_"));
|
|
31102
|
+
for (const variable of exported) env[variable.key] = variable.value;
|
|
31103
|
+
const unsetKeys = new Set([...parsePosixEnvUnsetKeys(existing), ...owned].filter((key) => !env[key]));
|
|
31104
|
+
const content = serializePosixEnvFile(env, unsetKeys);
|
|
31105
|
+
if (content !== existing) {
|
|
31106
|
+
import_fs4.default.writeFileSync(RUNTIME_ENV_FILE, content, { mode: 384 });
|
|
31107
|
+
import_fs4.default.chmodSync(RUNTIME_ENV_FILE, 384);
|
|
31108
|
+
}
|
|
31109
|
+
import_fs4.default.writeFileSync(EXPORTED_KEYS_FILE, JSON.stringify(exported.map((variable) => variable.key)), { mode: 384 });
|
|
31110
|
+
return exported.map((variable) => variable.key);
|
|
31111
|
+
}
|
|
31112
|
+
var formatDuration = (ms) => ms >= 6e4 ? `${Math.round(ms / 6e4)} minute(s)` : `${Math.round(ms / 1e3)} seconds`;
|
|
31113
|
+
async function environmentSetupWaitVariablesCommand(options) {
|
|
31114
|
+
const timeoutMs = parseWaitTimeoutMs(options.timeout);
|
|
31115
|
+
const wanted = options.keys ? new Set(options.keys.split(",").map((key) => key.trim()).filter(Boolean)) : null;
|
|
31116
|
+
const blocking = (requests) => requests.filter((request) => request.status === "pending" && (wanted ? wanted.has(request.key) : request.required));
|
|
31117
|
+
let { run } = await fetchCurrentRun();
|
|
31118
|
+
const before = run.variable_requests;
|
|
31119
|
+
if (blocking(before).length > 0) {
|
|
31120
|
+
console.log(import_chalk19.default.gray(`
|
|
31121
|
+
Waiting up to ${formatDuration(timeoutMs)} for: ${blocking(before).map((request) => request.key).join(", ")}`));
|
|
31122
|
+
const deadline = Date.now() + timeoutMs;
|
|
31123
|
+
while (blocking(run.variable_requests).length > 0 && Date.now() < deadline) {
|
|
31124
|
+
await new Promise((resolve2) => setTimeout(resolve2, ENVIRONMENT_SETUP_VARIABLE_WAIT.pollMs));
|
|
31125
|
+
run = (await fetchCurrentRun()).run;
|
|
31126
|
+
}
|
|
31127
|
+
}
|
|
31128
|
+
const { variables } = await orgAuthenticatedFetch("/v1/environment-setups/current/variables");
|
|
31129
|
+
const exported = exportToRuntimeEnv(variables);
|
|
31130
|
+
const reserved = variables.map((variable) => variable.key).filter((key) => !exported.includes(key));
|
|
31131
|
+
const byStatus = (status) => run.variable_requests.filter((request) => request.status === status).map((request) => request.key);
|
|
31132
|
+
const timedOut = blocking(run.variable_requests).map((request) => request.key);
|
|
31133
|
+
console.log("");
|
|
31134
|
+
if (exported.length > 0) console.log(` ${import_chalk19.default.green("Available in new shells:")} ${exported.join(", ")}`);
|
|
31135
|
+
if (reserved.length > 0) console.log(` ${import_chalk19.default.yellow("Reserved by Replicas:")} ${reserved.join(", ")} (reserved names, not exported; rename these in the proposal)`);
|
|
31136
|
+
if (byStatus("skipped").length > 0) console.log(` ${import_chalk19.default.gray("Skipped by the user:")} ${byStatus("skipped").join(", ")}`);
|
|
31137
|
+
if (timedOut.length > 0) console.log(` ${import_chalk19.default.yellow("Not answered in time:")} ${timedOut.join(", ")}`);
|
|
31138
|
+
if (variables.length === 0 && byStatus("skipped").length === 0 && timedOut.length === 0) console.log(import_chalk19.default.gray(" No variables were requested."));
|
|
31139
|
+
console.log(import_chalk19.default.gray("\n Values are never printed. Restart services you started before this command so they pick the variables up. Use a local substitute for anything skipped or unanswered and list it as required in the proposal.\n"));
|
|
31140
|
+
}
|
|
31141
|
+
|
|
31142
|
+
// src/commands/automation.ts
|
|
31143
|
+
var import_chalk20 = __toESM(require("chalk"));
|
|
30655
31144
|
var import_prompts7 = __toESM(require("prompts"));
|
|
30656
31145
|
function parseScopeFilter(value) {
|
|
30657
31146
|
if (!value) return void 0;
|
|
30658
31147
|
if (value === "org" || value === "user" || value === "all") return value;
|
|
30659
|
-
console.log(
|
|
30660
|
-
console.log(
|
|
31148
|
+
console.log(import_chalk20.default.red(`Invalid --owner: ${value}`));
|
|
31149
|
+
console.log(import_chalk20.default.gray("Valid options: org, user, all"));
|
|
30661
31150
|
process.exit(1);
|
|
30662
31151
|
}
|
|
30663
31152
|
function parseAgentProviderOption(value) {
|
|
@@ -30666,8 +31155,8 @@ function parseAgentProviderOption(value) {
|
|
|
30666
31155
|
if (trimmed === "" || trimmed.toLowerCase() === "none") return null;
|
|
30667
31156
|
const lower = trimmed.toLowerCase();
|
|
30668
31157
|
if (!isValidAgentProvider(lower)) {
|
|
30669
|
-
console.log(
|
|
30670
|
-
console.log(
|
|
31158
|
+
console.log(import_chalk20.default.red(`Invalid --agent-provider: ${value}`));
|
|
31159
|
+
console.log(import_chalk20.default.gray(`Valid options: ${VALID_AGENT_PROVIDERS.join(", ")}, none`));
|
|
30671
31160
|
process.exit(1);
|
|
30672
31161
|
}
|
|
30673
31162
|
return lower;
|
|
@@ -30678,8 +31167,8 @@ function parseThinkingLevelOption(value) {
|
|
|
30678
31167
|
if (trimmed === "" || trimmed.toLowerCase() === "none") return null;
|
|
30679
31168
|
const lower = trimmed.toLowerCase();
|
|
30680
31169
|
if (!isValidThinkingLevel(lower)) {
|
|
30681
|
-
console.log(
|
|
30682
|
-
console.log(
|
|
31170
|
+
console.log(import_chalk20.default.red(`Invalid --thinking-level: ${value}`));
|
|
31171
|
+
console.log(import_chalk20.default.gray(`Valid options: ${VALID_THINKING_LEVELS.join(", ")}, none`));
|
|
30683
31172
|
process.exit(1);
|
|
30684
31173
|
}
|
|
30685
31174
|
return lower;
|
|
@@ -30696,8 +31185,8 @@ function isAutomationLifecyclePolicy(value) {
|
|
|
30696
31185
|
function parseWorkspaceLifecyclePolicyOption(value) {
|
|
30697
31186
|
if (!value) return void 0;
|
|
30698
31187
|
if (isAutomationLifecyclePolicy(value)) return value;
|
|
30699
|
-
console.log(
|
|
30700
|
-
console.log(
|
|
31188
|
+
console.log(import_chalk20.default.red(`Invalid lifecycle policy: ${value}`));
|
|
31189
|
+
console.log(import_chalk20.default.gray(`Valid options: ${AUTOMATION_LIFECYCLE_POLICIES.join(", ")}`));
|
|
30701
31190
|
process.exit(1);
|
|
30702
31191
|
}
|
|
30703
31192
|
function parseExcludedActorsOption(value) {
|
|
@@ -30716,7 +31205,7 @@ function withExcludedActors(config3, excludedActors) {
|
|
|
30716
31205
|
}
|
|
30717
31206
|
function parseAutomationLifecycleOptions(options) {
|
|
30718
31207
|
if (options.sleepWhenDone && options.lifecycle && options.lifecycle !== "sleep_when_done") {
|
|
30719
|
-
console.log(
|
|
31208
|
+
console.log(import_chalk20.default.red("--sleep-when-done cannot be combined with a different --lifecycle value"));
|
|
30720
31209
|
process.exit(1);
|
|
30721
31210
|
}
|
|
30722
31211
|
if (options.sleepWhenDone) return "sleep_when_done";
|
|
@@ -30725,7 +31214,7 @@ function parseAutomationLifecycleOptions(options) {
|
|
|
30725
31214
|
function applyAgentSelection(body, existing) {
|
|
30726
31215
|
const result = validateAgentSelection(body, existing, AGENT_MODELS);
|
|
30727
31216
|
if (!result.ok) {
|
|
30728
|
-
console.log(
|
|
31217
|
+
console.log(import_chalk20.default.red(result.error.message));
|
|
30729
31218
|
process.exit(1);
|
|
30730
31219
|
}
|
|
30731
31220
|
const out = {};
|
|
@@ -30766,8 +31255,8 @@ function resolveTriggerRepositoryIds(repositories, repoNamesInput, provider) {
|
|
|
30766
31255
|
for (const repoName of repoNames) {
|
|
30767
31256
|
const repo = providerRepos.find((r) => r.name === repoName);
|
|
30768
31257
|
if (!repo) {
|
|
30769
|
-
console.log(
|
|
30770
|
-
console.log(
|
|
31258
|
+
console.log(import_chalk20.default.red(`Repository not found for ${provider} trigger filter: ${repoName}`));
|
|
31259
|
+
console.log(import_chalk20.default.gray(`Available: ${providerRepos.map((r) => r.name).join(", ")}`));
|
|
30771
31260
|
process.exit(1);
|
|
30772
31261
|
}
|
|
30773
31262
|
repoIds.push(repo.id);
|
|
@@ -30800,43 +31289,43 @@ function formatModeSummary(automation2) {
|
|
|
30800
31289
|
function resolveSelectableEnvironmentId(envInput, selectableEnvs) {
|
|
30801
31290
|
const resolved = resolveByNameOrId(envInput, selectableEnvs);
|
|
30802
31291
|
if (!resolved) {
|
|
30803
|
-
console.log(
|
|
31292
|
+
console.log(import_chalk20.default.red(`Environment not found: ${envInput}`));
|
|
30804
31293
|
const available = selectableEnvs.map((e) => e.name).join(", ");
|
|
30805
|
-
console.log(
|
|
31294
|
+
console.log(import_chalk20.default.gray(`Available: ${available || "(none)"}`));
|
|
30806
31295
|
process.exit(1);
|
|
30807
31296
|
}
|
|
30808
31297
|
return resolved.id;
|
|
30809
31298
|
}
|
|
30810
31299
|
function printAutomation(automation2) {
|
|
30811
|
-
console.log(
|
|
30812
|
-
console.log(
|
|
30813
|
-
console.log(
|
|
31300
|
+
console.log(import_chalk20.default.white(` ${automation2.name}`));
|
|
31301
|
+
console.log(import_chalk20.default.gray(` ID: ${automation2.id}`));
|
|
31302
|
+
console.log(import_chalk20.default.gray(` Owner: ${automation2.user_id ? "personal" : "organization"}`));
|
|
30814
31303
|
if (automation2.description) {
|
|
30815
|
-
console.log(
|
|
31304
|
+
console.log(import_chalk20.default.gray(` Description: ${automation2.description}`));
|
|
30816
31305
|
}
|
|
30817
|
-
console.log(
|
|
31306
|
+
console.log(import_chalk20.default.gray(` Enabled: ${automation2.enabled ? import_chalk20.default.green("yes") : import_chalk20.default.red("no")}`));
|
|
30818
31307
|
if (automation2.triggers.length > 0) {
|
|
30819
|
-
console.log(
|
|
31308
|
+
console.log(import_chalk20.default.gray(` Triggers: ${automation2.triggers.map(formatTrigger).join(", ")}`));
|
|
30820
31309
|
}
|
|
30821
31310
|
if (automation2.github_check_names.length > 0) {
|
|
30822
|
-
console.log(
|
|
31311
|
+
console.log(import_chalk20.default.gray(` GitHub checks: ${automation2.github_check_names.join(", ")}`));
|
|
30823
31312
|
}
|
|
30824
|
-
console.log(
|
|
31313
|
+
console.log(import_chalk20.default.gray(` Prompt: ${truncate2(automation2.prompt, 80)}`));
|
|
30825
31314
|
if (automation2.cron_next_fire_at) {
|
|
30826
|
-
console.log(
|
|
31315
|
+
console.log(import_chalk20.default.gray(` Next Run: ${formatDate2(automation2.cron_next_fire_at)}`));
|
|
30827
31316
|
}
|
|
30828
31317
|
if (automation2.workspace_lifecycle_policy && automation2.workspace_lifecycle_policy !== "default") {
|
|
30829
|
-
console.log(
|
|
31318
|
+
console.log(import_chalk20.default.gray(` Lifecycle: ${automation2.workspace_lifecycle_policy}`));
|
|
30830
31319
|
}
|
|
30831
31320
|
if (automation2.agent_provider || automation2.model || automation2.thinking_level) {
|
|
30832
|
-
console.log(
|
|
31321
|
+
console.log(import_chalk20.default.gray(` Agent: ${formatAgentSummary(automation2)}`));
|
|
30833
31322
|
}
|
|
30834
31323
|
if (automation2.plan_mode || automation2.goal_mode || automation2.fast_mode) {
|
|
30835
|
-
console.log(
|
|
31324
|
+
console.log(import_chalk20.default.gray(` Modes: ${formatModeSummary(automation2)}`));
|
|
30836
31325
|
}
|
|
30837
|
-
console.log(
|
|
30838
|
-
console.log(
|
|
30839
|
-
console.log(
|
|
31326
|
+
console.log(import_chalk20.default.gray(` PR Follow-ups: ${automation2.config.capabilities?.pr_followups === true ? import_chalk20.default.green("managed") : "read-only"}`));
|
|
31327
|
+
console.log(import_chalk20.default.gray(` Created: ${formatDate2(automation2.created_at)}`));
|
|
31328
|
+
console.log(import_chalk20.default.gray(` Updated: ${formatDate2(automation2.updated_at)}`));
|
|
30840
31329
|
console.log();
|
|
30841
31330
|
}
|
|
30842
31331
|
async function automationListCommand(options) {
|
|
@@ -30855,17 +31344,17 @@ async function automationListCommand(options) {
|
|
|
30855
31344
|
`/v1/automations${query ? "?" + query : ""}`
|
|
30856
31345
|
);
|
|
30857
31346
|
if (response.automations.length === 0) {
|
|
30858
|
-
console.log(
|
|
31347
|
+
console.log(import_chalk20.default.yellow("\nNo automations found.\n"));
|
|
30859
31348
|
return;
|
|
30860
31349
|
}
|
|
30861
|
-
console.log(
|
|
31350
|
+
console.log(import_chalk20.default.green(`
|
|
30862
31351
|
Automations (Page ${response.page} of ${response.totalPages}, Total: ${response.total}):
|
|
30863
31352
|
`));
|
|
30864
31353
|
for (const automation2 of response.automations) {
|
|
30865
31354
|
printAutomation(automation2);
|
|
30866
31355
|
}
|
|
30867
31356
|
} catch (error51) {
|
|
30868
|
-
console.error(
|
|
31357
|
+
console.error(import_chalk20.default.red(`Error: ${error51 instanceof Error ? error51.message : "Unknown error"}`));
|
|
30869
31358
|
process.exit(1);
|
|
30870
31359
|
}
|
|
30871
31360
|
}
|
|
@@ -30874,50 +31363,50 @@ async function automationGetCommand(id) {
|
|
|
30874
31363
|
try {
|
|
30875
31364
|
const response = await orgAuthenticatedFetch(`/v1/automations/${id}`);
|
|
30876
31365
|
const automation2 = response.automation;
|
|
30877
|
-
console.log(
|
|
31366
|
+
console.log(import_chalk20.default.green(`
|
|
30878
31367
|
Automation: ${automation2.name}
|
|
30879
31368
|
`));
|
|
30880
|
-
console.log(
|
|
31369
|
+
console.log(import_chalk20.default.gray(` ID: ${automation2.id}`));
|
|
30881
31370
|
if (automation2.description) {
|
|
30882
|
-
console.log(
|
|
31371
|
+
console.log(import_chalk20.default.gray(` Description: ${automation2.description}`));
|
|
30883
31372
|
}
|
|
30884
|
-
console.log(
|
|
31373
|
+
console.log(import_chalk20.default.gray(` Enabled: ${automation2.enabled ? import_chalk20.default.green("yes") : import_chalk20.default.red("no")}`));
|
|
30885
31374
|
if (automation2.triggers.length > 0) {
|
|
30886
|
-
console.log(
|
|
31375
|
+
console.log(import_chalk20.default.gray(` Triggers:`));
|
|
30887
31376
|
for (const trigger of automation2.triggers) {
|
|
30888
|
-
console.log(
|
|
31377
|
+
console.log(import_chalk20.default.gray(` - ${formatTrigger(trigger)}`));
|
|
30889
31378
|
}
|
|
30890
31379
|
}
|
|
30891
31380
|
if (automation2.github_check_names.length > 0) {
|
|
30892
|
-
console.log(
|
|
31381
|
+
console.log(import_chalk20.default.gray(` GitHub checks: ${automation2.github_check_names.join(", ")}`));
|
|
30893
31382
|
}
|
|
30894
|
-
console.log(
|
|
30895
|
-
console.log(
|
|
31383
|
+
console.log(import_chalk20.default.gray(` Prompt: ${automation2.prompt}`));
|
|
31384
|
+
console.log(import_chalk20.default.gray(` Environment: ${automation2.environment_id}`));
|
|
30896
31385
|
if (automation2.cron_expression) {
|
|
30897
|
-
console.log(
|
|
31386
|
+
console.log(import_chalk20.default.gray(` Cron: ${automation2.cron_expression}`));
|
|
30898
31387
|
}
|
|
30899
31388
|
if (automation2.cron_timezone) {
|
|
30900
|
-
console.log(
|
|
31389
|
+
console.log(import_chalk20.default.gray(` Timezone: ${automation2.cron_timezone}`));
|
|
30901
31390
|
}
|
|
30902
31391
|
if (automation2.cron_next_fire_at) {
|
|
30903
|
-
console.log(
|
|
31392
|
+
console.log(import_chalk20.default.gray(` Next Run: ${formatDate2(automation2.cron_next_fire_at)}`));
|
|
30904
31393
|
}
|
|
30905
31394
|
if (automation2.workspace_lifecycle_policy) {
|
|
30906
|
-
console.log(
|
|
31395
|
+
console.log(import_chalk20.default.gray(` Lifecycle Policy: ${automation2.workspace_lifecycle_policy}`));
|
|
30907
31396
|
}
|
|
30908
31397
|
if (automation2.workspace_auto_stop_minutes) {
|
|
30909
|
-
console.log(
|
|
30910
|
-
}
|
|
30911
|
-
console.log(
|
|
30912
|
-
console.log(
|
|
30913
|
-
console.log(
|
|
30914
|
-
console.log(
|
|
30915
|
-
console.log(
|
|
30916
|
-
console.log(
|
|
30917
|
-
console.log(
|
|
31398
|
+
console.log(import_chalk20.default.gray(` Auto-stop: ${automation2.workspace_auto_stop_minutes} minutes`));
|
|
31399
|
+
}
|
|
31400
|
+
console.log(import_chalk20.default.gray(` Agent: ${automation2.agent_provider ? getProviderDisplayName(automation2.agent_provider) : "organization default"}`));
|
|
31401
|
+
console.log(import_chalk20.default.gray(` Model: ${automation2.model ? MODEL_LABELS[automation2.model] ?? automation2.model : "agent default"}`));
|
|
31402
|
+
console.log(import_chalk20.default.gray(` Thinking Level: ${automation2.thinking_level ?? "agent default"}`));
|
|
31403
|
+
console.log(import_chalk20.default.gray(` Modes: ${formatModeSummary(automation2)}`));
|
|
31404
|
+
console.log(import_chalk20.default.gray(` PR Follow-ups: ${automation2.config.capabilities?.pr_followups === true ? "managed" : "read-only"}`));
|
|
31405
|
+
console.log(import_chalk20.default.gray(` Created: ${formatDate2(automation2.created_at)}`));
|
|
31406
|
+
console.log(import_chalk20.default.gray(` Updated: ${formatDate2(automation2.updated_at)}`));
|
|
30918
31407
|
console.log();
|
|
30919
31408
|
} catch (error51) {
|
|
30920
|
-
console.error(
|
|
31409
|
+
console.error(import_chalk20.default.red(`Error: ${error51 instanceof Error ? error51.message : "Unknown error"}`));
|
|
30921
31410
|
process.exit(1);
|
|
30922
31411
|
}
|
|
30923
31412
|
}
|
|
@@ -31042,22 +31531,22 @@ async function automationCreateCommand(name, options) {
|
|
|
31042
31531
|
ensureOrgApiAuthenticated();
|
|
31043
31532
|
const lifecyclePolicy = parseAutomationLifecycleOptions(options);
|
|
31044
31533
|
if (options.autoStopMinutes && !lifecyclePolicySupportsAutoStop(lifecyclePolicy ?? "default")) {
|
|
31045
|
-
console.log(
|
|
31534
|
+
console.log(import_chalk20.default.red("--auto-stop-minutes requires --lifecycle default"));
|
|
31046
31535
|
process.exit(1);
|
|
31047
31536
|
}
|
|
31048
31537
|
if (options.autoStopMinutes) {
|
|
31049
31538
|
const minutes = parseInt(options.autoStopMinutes, 10);
|
|
31050
31539
|
if (isNaN(minutes) || minutes < 3 || minutes > 1440) {
|
|
31051
|
-
console.log(
|
|
31540
|
+
console.log(import_chalk20.default.red("--auto-stop-minutes must be between 3 and 1440"));
|
|
31052
31541
|
process.exit(1);
|
|
31053
31542
|
}
|
|
31054
31543
|
}
|
|
31055
31544
|
if (options.triggerGithubExcludeUsers !== void 0 && !options.triggerGithub) {
|
|
31056
|
-
console.log(
|
|
31545
|
+
console.log(import_chalk20.default.red("--trigger-github-exclude-users requires --trigger-github"));
|
|
31057
31546
|
process.exit(1);
|
|
31058
31547
|
}
|
|
31059
31548
|
if (options.triggerGitlabExcludeUsers !== void 0 && !options.triggerGitlab) {
|
|
31060
|
-
console.log(
|
|
31549
|
+
console.log(import_chalk20.default.red("--trigger-gitlab-exclude-users requires --trigger-gitlab"));
|
|
31061
31550
|
process.exit(1);
|
|
31062
31551
|
}
|
|
31063
31552
|
const hasConfirmation = options.confirmationChannel || options.confirmationThread || options.confirmationMessageTs || options.confirmationUser;
|
|
@@ -31084,7 +31573,7 @@ async function automationCreateCommand(name, options) {
|
|
|
31084
31573
|
);
|
|
31085
31574
|
const selectableEnvs = envResponse.environments;
|
|
31086
31575
|
if (selectableEnvs.length === 0) {
|
|
31087
|
-
console.log(
|
|
31576
|
+
console.log(import_chalk20.default.red("No environments found. Please create an environment first."));
|
|
31088
31577
|
process.exit(1);
|
|
31089
31578
|
}
|
|
31090
31579
|
const repoResponse = await orgAuthenticatedFetch("/v1/repositories");
|
|
@@ -31098,7 +31587,7 @@ async function automationCreateCommand(name, options) {
|
|
|
31098
31587
|
validate: (value) => value.trim() ? true : "Name is required"
|
|
31099
31588
|
});
|
|
31100
31589
|
if (!response2.name) {
|
|
31101
|
-
console.log(
|
|
31590
|
+
console.log(import_chalk20.default.yellow("\nCancelled."));
|
|
31102
31591
|
return;
|
|
31103
31592
|
}
|
|
31104
31593
|
automationName = response2.name;
|
|
@@ -31112,7 +31601,7 @@ async function automationCreateCommand(name, options) {
|
|
|
31112
31601
|
validate: (value) => value.trim() ? true : "Prompt is required"
|
|
31113
31602
|
});
|
|
31114
31603
|
if (!response2.prompt) {
|
|
31115
|
-
console.log(
|
|
31604
|
+
console.log(import_chalk20.default.yellow("\nCancelled."));
|
|
31116
31605
|
return;
|
|
31117
31606
|
}
|
|
31118
31607
|
automationPrompt = response2.prompt;
|
|
@@ -31132,7 +31621,7 @@ async function automationCreateCommand(name, options) {
|
|
|
31132
31621
|
}))
|
|
31133
31622
|
});
|
|
31134
31623
|
if (!envResponse2.env) {
|
|
31135
|
-
console.log(
|
|
31624
|
+
console.log(import_chalk20.default.yellow("\nCancelled."));
|
|
31136
31625
|
return;
|
|
31137
31626
|
}
|
|
31138
31627
|
selectedEnvironmentId = envResponse2.env;
|
|
@@ -31174,7 +31663,7 @@ async function automationCreateCommand(name, options) {
|
|
|
31174
31663
|
if (triggers.length === 0) {
|
|
31175
31664
|
triggers = await promptForTriggers(repositories.map((r) => ({ id: r.id, name: r.name, provider: r.provider })));
|
|
31176
31665
|
if (triggers.length === 0) {
|
|
31177
|
-
console.log(
|
|
31666
|
+
console.log(import_chalk20.default.red("At least one trigger is required."));
|
|
31178
31667
|
process.exit(1);
|
|
31179
31668
|
}
|
|
31180
31669
|
}
|
|
@@ -31205,25 +31694,25 @@ async function automationCreateCommand(name, options) {
|
|
|
31205
31694
|
...agentSelection,
|
|
31206
31695
|
...mothershipConfirmation ? { mothership_confirmation: mothershipConfirmation } : {}
|
|
31207
31696
|
};
|
|
31208
|
-
console.log(
|
|
31697
|
+
console.log(import_chalk20.default.gray("\nCreating automation..."));
|
|
31209
31698
|
const response = await orgAuthenticatedFetch("/v1/automations", {
|
|
31210
31699
|
method: "POST",
|
|
31211
31700
|
body
|
|
31212
31701
|
});
|
|
31213
31702
|
const automation2 = response.automation;
|
|
31214
|
-
console.log(
|
|
31703
|
+
console.log(import_chalk20.default.green(`
|
|
31215
31704
|
Created automation: ${automation2.name}`));
|
|
31216
|
-
console.log(
|
|
31217
|
-
console.log(
|
|
31705
|
+
console.log(import_chalk20.default.gray(` ID: ${automation2.id}`));
|
|
31706
|
+
console.log(import_chalk20.default.gray(` Enabled: ${automation2.enabled ? "yes" : "no"}`));
|
|
31218
31707
|
if (automation2.triggers.length > 0) {
|
|
31219
|
-
console.log(
|
|
31708
|
+
console.log(import_chalk20.default.gray(` Triggers: ${automation2.triggers.map(formatTrigger).join(", ")}`));
|
|
31220
31709
|
}
|
|
31221
31710
|
if (automation2.cron_next_fire_at) {
|
|
31222
|
-
console.log(
|
|
31711
|
+
console.log(import_chalk20.default.gray(` Next Run: ${formatDate2(automation2.cron_next_fire_at)}`));
|
|
31223
31712
|
}
|
|
31224
31713
|
console.log();
|
|
31225
31714
|
} catch (error51) {
|
|
31226
|
-
console.error(
|
|
31715
|
+
console.error(import_chalk20.default.red(`Error: ${error51 instanceof Error ? error51.message : "Unknown error"}`));
|
|
31227
31716
|
process.exit(1);
|
|
31228
31717
|
}
|
|
31229
31718
|
}
|
|
@@ -31233,17 +31722,17 @@ async function automationEditCommand(id, options) {
|
|
|
31233
31722
|
if (options.autoStopMinutes) {
|
|
31234
31723
|
const minutes = parseInt(options.autoStopMinutes, 10);
|
|
31235
31724
|
if (isNaN(minutes) || minutes < 3 || minutes > 1440) {
|
|
31236
|
-
console.log(
|
|
31725
|
+
console.log(import_chalk20.default.red("--auto-stop-minutes must be between 3 and 1440"));
|
|
31237
31726
|
process.exit(1);
|
|
31238
31727
|
}
|
|
31239
31728
|
}
|
|
31240
31729
|
const replacingTriggers = Boolean(options.triggerCron || options.triggerGithub || options.triggerGitlab);
|
|
31241
31730
|
if (replacingTriggers && options.triggerGithubExcludeUsers !== void 0 && !options.triggerGithub) {
|
|
31242
|
-
console.log(
|
|
31731
|
+
console.log(import_chalk20.default.red("--trigger-github-exclude-users requires --trigger-github when replacing triggers"));
|
|
31243
31732
|
process.exit(1);
|
|
31244
31733
|
}
|
|
31245
31734
|
if (replacingTriggers && options.triggerGitlabExcludeUsers !== void 0 && !options.triggerGitlab) {
|
|
31246
|
-
console.log(
|
|
31735
|
+
console.log(import_chalk20.default.red("--trigger-gitlab-exclude-users requires --trigger-gitlab when replacing triggers"));
|
|
31247
31736
|
process.exit(1);
|
|
31248
31737
|
}
|
|
31249
31738
|
const parsedAgent = {
|
|
@@ -31255,7 +31744,7 @@ async function automationEditCommand(id, options) {
|
|
|
31255
31744
|
const existing = await orgAuthenticatedFetch(`/v1/automations/${id}`);
|
|
31256
31745
|
const autoStopLifecyclePolicy = lifecyclePolicy ?? toAutomationLifecyclePolicy(existing.automation.workspace_lifecycle_policy);
|
|
31257
31746
|
if (options.autoStopMinutes && !lifecyclePolicySupportsAutoStop(autoStopLifecyclePolicy)) {
|
|
31258
|
-
console.log(
|
|
31747
|
+
console.log(import_chalk20.default.red("--auto-stop-minutes requires --lifecycle default"));
|
|
31259
31748
|
process.exit(1);
|
|
31260
31749
|
}
|
|
31261
31750
|
const agentSelection = applyAgentSelection(parsedAgent, {
|
|
@@ -31395,11 +31884,11 @@ async function automationEditCommand(id, options) {
|
|
|
31395
31884
|
return trigger;
|
|
31396
31885
|
});
|
|
31397
31886
|
if (!matchedGithub) {
|
|
31398
|
-
console.log(
|
|
31887
|
+
console.log(import_chalk20.default.red("No existing GitHub trigger found. Pass --trigger-github to create one."));
|
|
31399
31888
|
process.exit(1);
|
|
31400
31889
|
}
|
|
31401
31890
|
if (!matchedGitlab) {
|
|
31402
|
-
console.log(
|
|
31891
|
+
console.log(import_chalk20.default.red("No existing GitLab trigger found. Pass --trigger-gitlab to create one."));
|
|
31403
31892
|
process.exit(1);
|
|
31404
31893
|
}
|
|
31405
31894
|
}
|
|
@@ -31424,25 +31913,25 @@ async function automationEditCommand(id, options) {
|
|
|
31424
31913
|
Object.assign(body, agentSelection);
|
|
31425
31914
|
}
|
|
31426
31915
|
if (Object.keys(body).length === 0) {
|
|
31427
|
-
console.log(
|
|
31916
|
+
console.log(import_chalk20.default.yellow("\nNo changes made.\n"));
|
|
31428
31917
|
return;
|
|
31429
31918
|
}
|
|
31430
|
-
console.log(
|
|
31919
|
+
console.log(import_chalk20.default.gray("\nUpdating automation..."));
|
|
31431
31920
|
const response = await orgAuthenticatedFetch(`/v1/automations/${id}`, {
|
|
31432
31921
|
method: "PATCH",
|
|
31433
31922
|
body
|
|
31434
31923
|
});
|
|
31435
31924
|
const automation2 = response.automation;
|
|
31436
|
-
console.log(
|
|
31925
|
+
console.log(import_chalk20.default.green(`
|
|
31437
31926
|
Updated automation: ${automation2.name}`));
|
|
31438
|
-
console.log(
|
|
31439
|
-
console.log(
|
|
31927
|
+
console.log(import_chalk20.default.gray(` ID: ${automation2.id}`));
|
|
31928
|
+
console.log(import_chalk20.default.gray(` Enabled: ${automation2.enabled ? "yes" : "no"}`));
|
|
31440
31929
|
if (automation2.triggers.length > 0) {
|
|
31441
|
-
console.log(
|
|
31930
|
+
console.log(import_chalk20.default.gray(` Triggers: ${automation2.triggers.map(formatTrigger).join(", ")}`));
|
|
31442
31931
|
}
|
|
31443
31932
|
console.log();
|
|
31444
31933
|
} catch (error51) {
|
|
31445
|
-
console.error(
|
|
31934
|
+
console.error(import_chalk20.default.red(`Error: ${error51 instanceof Error ? error51.message : "Unknown error"}`));
|
|
31446
31935
|
process.exit(1);
|
|
31447
31936
|
}
|
|
31448
31937
|
}
|
|
@@ -31453,12 +31942,12 @@ async function automationRunCommand(id) {
|
|
|
31453
31942
|
const automation2 = existing.automation;
|
|
31454
31943
|
const hasCronTrigger = automation2.triggers.some((t) => t.type === "cron");
|
|
31455
31944
|
if (!hasCronTrigger) {
|
|
31456
|
-
console.log(
|
|
31457
|
-
console.log(
|
|
31945
|
+
console.log(import_chalk20.default.red("\nManual run is only allowed for automations with a cron trigger."));
|
|
31946
|
+
console.log(import_chalk20.default.gray(`This automation has triggers: ${automation2.triggers.map(formatTrigger).join(", ")}`));
|
|
31458
31947
|
console.log();
|
|
31459
31948
|
process.exit(1);
|
|
31460
31949
|
}
|
|
31461
|
-
console.log(
|
|
31950
|
+
console.log(import_chalk20.default.gray(`
|
|
31462
31951
|
Triggering automation "${automation2.name}"...`));
|
|
31463
31952
|
const response = await orgAuthenticatedFetch(
|
|
31464
31953
|
`/v1/automations/${id}/trigger`,
|
|
@@ -31468,20 +31957,20 @@ Triggering automation "${automation2.name}"...`));
|
|
|
31468
31957
|
}
|
|
31469
31958
|
);
|
|
31470
31959
|
if (!response.execution_id) {
|
|
31471
|
-
console.log(
|
|
31960
|
+
console.log(import_chalk20.default.red(`
|
|
31472
31961
|
Automation trigger returned no execution ID. The automation may not have started.`));
|
|
31473
31962
|
console.log();
|
|
31474
31963
|
process.exit(1);
|
|
31475
31964
|
}
|
|
31476
|
-
console.log(
|
|
31965
|
+
console.log(import_chalk20.default.green(`
|
|
31477
31966
|
Automation triggered successfully.`));
|
|
31478
|
-
console.log(
|
|
31967
|
+
console.log(import_chalk20.default.gray(` Execution ID: ${response.execution_id}`));
|
|
31479
31968
|
if (response.workspace_id) {
|
|
31480
|
-
console.log(
|
|
31969
|
+
console.log(import_chalk20.default.gray(` Workspace ID: ${response.workspace_id}`));
|
|
31481
31970
|
}
|
|
31482
31971
|
console.log();
|
|
31483
31972
|
} catch (error51) {
|
|
31484
|
-
console.error(
|
|
31973
|
+
console.error(import_chalk20.default.red(`Error: ${error51 instanceof Error ? error51.message : "Unknown error"}`));
|
|
31485
31974
|
process.exit(1);
|
|
31486
31975
|
}
|
|
31487
31976
|
}
|
|
@@ -31498,38 +31987,38 @@ async function automationDeleteCommand(id, options) {
|
|
|
31498
31987
|
initial: false
|
|
31499
31988
|
});
|
|
31500
31989
|
if (!response.confirm) {
|
|
31501
|
-
console.log(
|
|
31990
|
+
console.log(import_chalk20.default.yellow("\nCancelled."));
|
|
31502
31991
|
return;
|
|
31503
31992
|
}
|
|
31504
31993
|
}
|
|
31505
31994
|
await orgAuthenticatedFetch(`/v1/automations/${id}`, {
|
|
31506
31995
|
method: "DELETE"
|
|
31507
31996
|
});
|
|
31508
|
-
console.log(
|
|
31997
|
+
console.log(import_chalk20.default.green(`
|
|
31509
31998
|
Automation "${automationName}" (${id}) deleted.
|
|
31510
31999
|
`));
|
|
31511
32000
|
} catch (error51) {
|
|
31512
|
-
console.error(
|
|
32001
|
+
console.error(import_chalk20.default.red(`Error: ${error51 instanceof Error ? error51.message : "Unknown error"}`));
|
|
31513
32002
|
process.exit(1);
|
|
31514
32003
|
}
|
|
31515
32004
|
}
|
|
31516
32005
|
async function automationCheckCommand(checkRunId, options) {
|
|
31517
32006
|
const id = Number(checkRunId);
|
|
31518
32007
|
if (!Number.isSafeInteger(id)) {
|
|
31519
|
-
console.error(
|
|
32008
|
+
console.error(import_chalk20.default.red("Error: check run ID must be an integer"));
|
|
31520
32009
|
process.exit(1);
|
|
31521
32010
|
}
|
|
31522
32011
|
if (!options.token) {
|
|
31523
|
-
console.error(
|
|
32012
|
+
console.error(import_chalk20.default.red("Error: --token is required"));
|
|
31524
32013
|
process.exit(1);
|
|
31525
32014
|
}
|
|
31526
32015
|
const { conclusion } = options;
|
|
31527
32016
|
if (!isAutomationCheckConclusion(conclusion)) {
|
|
31528
|
-
console.error(
|
|
32017
|
+
console.error(import_chalk20.default.red(`Error: --conclusion must be one of ${AUTOMATION_CHECK_CONCLUSIONS.join(", ")}`));
|
|
31529
32018
|
process.exit(1);
|
|
31530
32019
|
}
|
|
31531
32020
|
if (!options.title?.trim()) {
|
|
31532
|
-
console.error(
|
|
32021
|
+
console.error(import_chalk20.default.red("Error: --title is required"));
|
|
31533
32022
|
process.exit(1);
|
|
31534
32023
|
}
|
|
31535
32024
|
const body = {
|
|
@@ -31543,23 +32032,23 @@ async function automationCheckCommand(checkRunId, options) {
|
|
|
31543
32032
|
`/v1/automations/checks/${id}`,
|
|
31544
32033
|
{ method: "POST", body }
|
|
31545
32034
|
);
|
|
31546
|
-
console.log(response.reported ?
|
|
32035
|
+
console.log(response.reported ? import_chalk20.default.green(`
|
|
31547
32036
|
Reported ${conclusion} for "${response.name}".
|
|
31548
|
-
`) :
|
|
32037
|
+
`) : import_chalk20.default.yellow(`
|
|
31549
32038
|
Skipped "${response.name}" \u2014 a newer run of this automation owns it and will report the verdict.
|
|
31550
32039
|
`));
|
|
31551
32040
|
} catch (error51) {
|
|
31552
|
-
console.error(
|
|
32041
|
+
console.error(import_chalk20.default.red(`Error: ${error51 instanceof Error ? error51.message : "Unknown error"}`));
|
|
31553
32042
|
process.exit(1);
|
|
31554
32043
|
}
|
|
31555
32044
|
}
|
|
31556
32045
|
|
|
31557
32046
|
// src/commands/preview.ts
|
|
31558
|
-
var
|
|
32047
|
+
var import_chalk21 = __toESM(require("chalk"));
|
|
31559
32048
|
|
|
31560
32049
|
// src/lib/agent-api.ts
|
|
31561
32050
|
var ENGINE_PORT = process.env.REPLICAS_ENGINE_PORT || "3737";
|
|
31562
|
-
async function agentFetch(
|
|
32051
|
+
async function agentFetch(path7, options) {
|
|
31563
32052
|
const config3 = readAgentConfig();
|
|
31564
32053
|
if (!config3) {
|
|
31565
32054
|
throw new Error("Agent mode config not found");
|
|
@@ -31573,7 +32062,7 @@ async function agentFetch(path6, options) {
|
|
|
31573
32062
|
...options?.headers || {}
|
|
31574
32063
|
};
|
|
31575
32064
|
const body = options?.body === void 0 ? void 0 : isFormData ? options.body : JSON.stringify(options.body);
|
|
31576
|
-
const response = await fetch(`${MONOLITH_URL}${
|
|
32065
|
+
const response = await fetch(`${MONOLITH_URL}${path7}`, {
|
|
31577
32066
|
...options,
|
|
31578
32067
|
headers,
|
|
31579
32068
|
body
|
|
@@ -31584,7 +32073,7 @@ async function agentFetch(path6, options) {
|
|
|
31584
32073
|
}
|
|
31585
32074
|
return response.json();
|
|
31586
32075
|
}
|
|
31587
|
-
async function engineFetch(
|
|
32076
|
+
async function engineFetch(path7, options) {
|
|
31588
32077
|
const config3 = readAgentConfig();
|
|
31589
32078
|
if (!config3) {
|
|
31590
32079
|
throw new Error("Agent mode config not found");
|
|
@@ -31594,7 +32083,7 @@ async function engineFetch(path6, options) {
|
|
|
31594
32083
|
"Content-Type": "application/json",
|
|
31595
32084
|
...options?.headers || {}
|
|
31596
32085
|
};
|
|
31597
|
-
const response = await fetch(`http://localhost:${ENGINE_PORT}${
|
|
32086
|
+
const response = await fetch(`http://localhost:${ENGINE_PORT}${path7}`, {
|
|
31598
32087
|
...options,
|
|
31599
32088
|
headers,
|
|
31600
32089
|
body: options?.body !== void 0 ? JSON.stringify(options.body) : void 0
|
|
@@ -31649,11 +32138,11 @@ async function previewListCommand(workspaceId) {
|
|
|
31649
32138
|
`/v1/workspaces/${workspaceId}/previews`
|
|
31650
32139
|
);
|
|
31651
32140
|
if (result.previews.length === 0) {
|
|
31652
|
-
console.log(
|
|
32141
|
+
console.log(import_chalk21.default.dim("No active previews"));
|
|
31653
32142
|
return;
|
|
31654
32143
|
}
|
|
31655
32144
|
for (const preview2 of result.previews) {
|
|
31656
|
-
console.log(` ${
|
|
32145
|
+
console.log(` ${import_chalk21.default.cyan(String(preview2.port))} \u2192 ${import_chalk21.default.underline(preview2.publicUrl)}`);
|
|
31657
32146
|
}
|
|
31658
32147
|
}
|
|
31659
32148
|
}
|
|
@@ -31666,7 +32155,7 @@ async function previewAddCommand(workspaceId, options) {
|
|
|
31666
32155
|
body: { port: portNum, authenticated: options.authenticated ?? false }
|
|
31667
32156
|
}
|
|
31668
32157
|
);
|
|
31669
|
-
console.log(
|
|
32158
|
+
console.log(import_chalk21.default.green(`Preview created: ${result.preview.publicUrl}`));
|
|
31670
32159
|
}
|
|
31671
32160
|
async function previewDeleteCommand(port) {
|
|
31672
32161
|
const portNum = parsePreviewPort(port);
|
|
@@ -31679,12 +32168,12 @@ async function previewRemoveCommand(workspaceId, options) {
|
|
|
31679
32168
|
`/v1/workspaces/${workspaceId}/previews/${portNum}`,
|
|
31680
32169
|
{ method: "DELETE" }
|
|
31681
32170
|
);
|
|
31682
|
-
console.log(
|
|
32171
|
+
console.log(import_chalk21.default.green(`Preview deleted on port ${portNum}`));
|
|
31683
32172
|
}
|
|
31684
32173
|
|
|
31685
32174
|
// src/commands/media.ts
|
|
31686
|
-
var
|
|
31687
|
-
var
|
|
32175
|
+
var import_fs5 = __toESM(require("fs"));
|
|
32176
|
+
var import_path6 = __toESM(require("path"));
|
|
31688
32177
|
var MEDIA_ACCESS_VALUES = ["organization", "public"];
|
|
31689
32178
|
function publicMediaUrl(mediaId, token) {
|
|
31690
32179
|
return `${MONOLITH_URL}/v1/media/public/${mediaId}/${token}`;
|
|
@@ -31724,22 +32213,22 @@ function resolveKind(ext, override) {
|
|
|
31724
32213
|
return inferred;
|
|
31725
32214
|
}
|
|
31726
32215
|
async function uploadOne(filePath, displayName, kind, options) {
|
|
31727
|
-
const absPath =
|
|
31728
|
-
if (!
|
|
32216
|
+
const absPath = import_path6.default.resolve(filePath);
|
|
32217
|
+
if (!import_fs5.default.existsSync(absPath)) {
|
|
31729
32218
|
throw new Error(`File not found: ${absPath}`);
|
|
31730
32219
|
}
|
|
31731
|
-
const stat =
|
|
32220
|
+
const stat = import_fs5.default.statSync(absPath);
|
|
31732
32221
|
if (!stat.isFile()) {
|
|
31733
32222
|
throw new Error(`Not a file: ${absPath}`);
|
|
31734
32223
|
}
|
|
31735
32224
|
if (stat.size === 0) {
|
|
31736
32225
|
throw new Error("File is empty");
|
|
31737
32226
|
}
|
|
31738
|
-
const fileName =
|
|
31739
|
-
const ext =
|
|
32227
|
+
const fileName = import_path6.default.basename(absPath);
|
|
32228
|
+
const ext = import_path6.default.extname(absPath).slice(1).toLowerCase();
|
|
31740
32229
|
const contentType = mediaInfo(ext)?.contentType ?? "application/octet-stream";
|
|
31741
32230
|
const form = new FormData();
|
|
31742
|
-
form.append("file", new Blob([
|
|
32231
|
+
form.append("file", new Blob([import_fs5.default.readFileSync(absPath)], { type: contentType }), fileName);
|
|
31743
32232
|
form.append("kind", kind);
|
|
31744
32233
|
if (options.sessionId) form.append("session_id", options.sessionId);
|
|
31745
32234
|
form.append("display_name", displayName);
|
|
@@ -31773,7 +32262,7 @@ async function mediaUploadCommand(filePaths, options) {
|
|
|
31773
32262
|
}
|
|
31774
32263
|
const publicAccess = options.share || options.access === "public";
|
|
31775
32264
|
const kinds = filePaths.map((filePath) => {
|
|
31776
|
-
const ext =
|
|
32265
|
+
const ext = import_path6.default.extname(filePath).slice(1).toLowerCase();
|
|
31777
32266
|
return resolveKind(ext, options.kind);
|
|
31778
32267
|
});
|
|
31779
32268
|
if (publicAccess && kinds.some((kind) => !isPublicMediaKind(kind))) {
|
|
@@ -31859,7 +32348,7 @@ async function mediaListCommand(options) {
|
|
|
31859
32348
|
}
|
|
31860
32349
|
|
|
31861
32350
|
// src/commands/slack.ts
|
|
31862
|
-
var
|
|
32351
|
+
var import_chalk22 = __toESM(require("chalk"));
|
|
31863
32352
|
function getThreadOptions(options) {
|
|
31864
32353
|
const channelId = options.channel || process.env.REPLICAS_SLACK_CHANNEL_ID || process.env.SLACK_CHANNEL_ID;
|
|
31865
32354
|
const threadTs = options.threadTs || process.env.REPLICAS_SLACK_THREAD_TS || process.env.SLACK_THREAD_TS;
|
|
@@ -31876,10 +32365,10 @@ async function attachThread(request) {
|
|
|
31876
32365
|
method: "POST",
|
|
31877
32366
|
body: request
|
|
31878
32367
|
});
|
|
31879
|
-
console.log(
|
|
31880
|
-
console.log(
|
|
31881
|
-
console.log(
|
|
31882
|
-
console.log(
|
|
32368
|
+
console.log(import_chalk22.default.green("Slack thread attached."));
|
|
32369
|
+
console.log(import_chalk22.default.gray(` Channel: ${response.thread.channel_id}`));
|
|
32370
|
+
console.log(import_chalk22.default.gray(` Thread: ${response.thread.thread_ts}`));
|
|
32371
|
+
console.log(import_chalk22.default.gray(` Workspace: ${response.workspace.name} (${response.workspace.id})`));
|
|
31883
32372
|
}
|
|
31884
32373
|
async function slackThreadAttachCommand(options) {
|
|
31885
32374
|
const agentConfig = readAgentConfig();
|
|
@@ -31908,7 +32397,7 @@ async function slackThreadSwitchCommand(workspace, options) {
|
|
|
31908
32397
|
}
|
|
31909
32398
|
|
|
31910
32399
|
// src/commands/service.ts
|
|
31911
|
-
var
|
|
32400
|
+
var import_chalk23 = __toESM(require("chalk"));
|
|
31912
32401
|
var import_node_child_process2 = require("child_process");
|
|
31913
32402
|
var import_node_fs2 = require("fs");
|
|
31914
32403
|
var import_node_os2 = require("os");
|
|
@@ -32051,7 +32540,7 @@ async function serviceListCommand() {
|
|
|
32051
32540
|
return;
|
|
32052
32541
|
}
|
|
32053
32542
|
for (const state of states) {
|
|
32054
|
-
const status = isRunning(state.pid) ?
|
|
32543
|
+
const status = isRunning(state.pid) ? import_chalk23.default.green("running") : import_chalk23.default.red("stopped");
|
|
32055
32544
|
console.log(`${state.name} ${status} pid ${state.pid} started ${state.startedAt}`);
|
|
32056
32545
|
console.log(` command: ${state.command} (cwd: ${state.cwd})`);
|
|
32057
32546
|
console.log(` logs: ${state.logFile}`);
|
|
@@ -32157,8 +32646,8 @@ Workspace: ${workspaceNameForOutput(result.workspace_name)} (${getWorkspaceDashb
|
|
|
32157
32646
|
}
|
|
32158
32647
|
|
|
32159
32648
|
// src/commands/environment.ts
|
|
32160
|
-
var
|
|
32161
|
-
var
|
|
32649
|
+
var import_fs6 = __toESM(require("fs"));
|
|
32650
|
+
var import_chalk24 = __toESM(require("chalk"));
|
|
32162
32651
|
var import_prompts8 = __toESM(require("prompts"));
|
|
32163
32652
|
function maskValue(value) {
|
|
32164
32653
|
if (value.length <= 4) return "\u2022\u2022\u2022\u2022";
|
|
@@ -32170,38 +32659,38 @@ async function resolveEnvironmentId(input) {
|
|
|
32170
32659
|
const response = await orgAuthenticatedFetch("/v1/environments");
|
|
32171
32660
|
const resolved = resolveByNameOrId(input, response.environments);
|
|
32172
32661
|
if (!resolved) {
|
|
32173
|
-
console.log(
|
|
32662
|
+
console.log(import_chalk24.default.red(`Environment not found: ${input}`));
|
|
32174
32663
|
const available = response.environments.map((e) => e.name).join(", ");
|
|
32175
|
-
console.log(
|
|
32664
|
+
console.log(import_chalk24.default.gray(`Available: ${available || "(none)"}`));
|
|
32176
32665
|
process.exit(1);
|
|
32177
32666
|
}
|
|
32178
32667
|
return resolved.id;
|
|
32179
32668
|
}
|
|
32180
32669
|
function printEnvironment(env) {
|
|
32181
|
-
console.log(
|
|
32182
|
-
console.log(
|
|
32670
|
+
console.log(import_chalk24.default.white(` ${env.name}${env.is_global ? import_chalk24.default.gray(" (global)") : ""}`));
|
|
32671
|
+
console.log(import_chalk24.default.gray(` ID: ${env.id}`));
|
|
32183
32672
|
if (env.description) {
|
|
32184
|
-
console.log(
|
|
32673
|
+
console.log(import_chalk24.default.gray(` Description: ${env.description}`));
|
|
32185
32674
|
}
|
|
32186
32675
|
if (env.repository_id) {
|
|
32187
|
-
console.log(
|
|
32676
|
+
console.log(import_chalk24.default.gray(` Repository: ${env.repository_id}`));
|
|
32188
32677
|
} else if (env.repository_set_id) {
|
|
32189
|
-
console.log(
|
|
32678
|
+
console.log(import_chalk24.default.gray(` Repository Set: ${env.repository_set_id}`));
|
|
32190
32679
|
}
|
|
32191
32680
|
if (env.variable_count !== void 0) {
|
|
32192
|
-
console.log(
|
|
32681
|
+
console.log(import_chalk24.default.gray(` Variables: ${env.variable_count}, Files: ${env.file_count ?? 0}, Skills: ${env.skill_count ?? 0}, MCPs: ${env.mcp_count ?? 0}`));
|
|
32193
32682
|
}
|
|
32194
|
-
console.log(
|
|
32683
|
+
console.log(import_chalk24.default.gray(` Updated: ${formatDate2(env.updated_at)}`));
|
|
32195
32684
|
console.log();
|
|
32196
32685
|
}
|
|
32197
32686
|
async function environmentListCommand() {
|
|
32198
32687
|
ensureOrgApiAuthenticated();
|
|
32199
32688
|
const response = await orgAuthenticatedFetch("/v1/environments");
|
|
32200
32689
|
if (response.environments.length === 0) {
|
|
32201
|
-
console.log(
|
|
32690
|
+
console.log(import_chalk24.default.yellow("\nNo environments found.\n"));
|
|
32202
32691
|
return;
|
|
32203
32692
|
}
|
|
32204
|
-
console.log(
|
|
32693
|
+
console.log(import_chalk24.default.green(`
|
|
32205
32694
|
Environments (${response.environments.length}):
|
|
32206
32695
|
`));
|
|
32207
32696
|
for (const env of response.environments) {
|
|
@@ -32212,7 +32701,7 @@ async function environmentGetCommand(idOrName) {
|
|
|
32212
32701
|
ensureOrgApiAuthenticated();
|
|
32213
32702
|
const id = await resolveEnvironmentId(idOrName);
|
|
32214
32703
|
const response = await orgAuthenticatedFetch(`/v1/environments/${id}`);
|
|
32215
|
-
console.log(
|
|
32704
|
+
console.log(import_chalk24.default.green(`
|
|
32216
32705
|
Environment: ${response.environment.name}
|
|
32217
32706
|
`));
|
|
32218
32707
|
printEnvironment(response.environment);
|
|
@@ -32228,7 +32717,7 @@ async function environmentCreateCommand(name, options) {
|
|
|
32228
32717
|
validate: (v) => v.trim() ? true : "Name is required"
|
|
32229
32718
|
});
|
|
32230
32719
|
if (!r.name) {
|
|
32231
|
-
console.log(
|
|
32720
|
+
console.log(import_chalk24.default.yellow("\nCancelled."));
|
|
32232
32721
|
return;
|
|
32233
32722
|
}
|
|
32234
32723
|
envName = r.name;
|
|
@@ -32241,8 +32730,8 @@ async function environmentCreateCommand(name, options) {
|
|
|
32241
32730
|
const repos2 = await orgAuthenticatedFetch("/v1/repositories");
|
|
32242
32731
|
const repo = repos2.repositories.find((r) => r.name === options.repository);
|
|
32243
32732
|
if (!repo) {
|
|
32244
|
-
console.log(
|
|
32245
|
-
console.log(
|
|
32733
|
+
console.log(import_chalk24.default.red(`Repository not found: ${options.repository}`));
|
|
32734
|
+
console.log(import_chalk24.default.gray(`Available: ${repos2.repositories.map((r) => r.name).join(", ")}`));
|
|
32246
32735
|
process.exit(1);
|
|
32247
32736
|
}
|
|
32248
32737
|
repositoryId = repo.id;
|
|
@@ -32272,9 +32761,9 @@ async function environmentCreateCommand(name, options) {
|
|
|
32272
32761
|
method: "POST",
|
|
32273
32762
|
body
|
|
32274
32763
|
});
|
|
32275
|
-
console.log(
|
|
32764
|
+
console.log(import_chalk24.default.green(`
|
|
32276
32765
|
Created environment: ${response.environment.name}`));
|
|
32277
|
-
console.log(
|
|
32766
|
+
console.log(import_chalk24.default.gray(` ID: ${response.environment.id}
|
|
32278
32767
|
`));
|
|
32279
32768
|
}
|
|
32280
32769
|
async function environmentEditCommand(idOrName, options) {
|
|
@@ -32293,21 +32782,21 @@ async function environmentEditCommand(idOrName, options) {
|
|
|
32293
32782
|
const repos2 = await orgAuthenticatedFetch("/v1/repositories");
|
|
32294
32783
|
const repo = repos2.repositories.find((r) => r.name === options.repository);
|
|
32295
32784
|
if (!repo) {
|
|
32296
|
-
console.log(
|
|
32785
|
+
console.log(import_chalk24.default.red(`Repository not found: ${options.repository}`));
|
|
32297
32786
|
process.exit(1);
|
|
32298
32787
|
}
|
|
32299
32788
|
body.repository_id = repo.id;
|
|
32300
32789
|
}
|
|
32301
32790
|
}
|
|
32302
32791
|
if (Object.keys(body).length === 0) {
|
|
32303
|
-
console.log(
|
|
32792
|
+
console.log(import_chalk24.default.yellow("\nNo changes specified. Pass --name, --description, --repository, or --system-prompt."));
|
|
32304
32793
|
return;
|
|
32305
32794
|
}
|
|
32306
32795
|
const response = await orgAuthenticatedFetch(`/v1/environments/${id}`, {
|
|
32307
32796
|
method: "PATCH",
|
|
32308
32797
|
body
|
|
32309
32798
|
});
|
|
32310
|
-
console.log(
|
|
32799
|
+
console.log(import_chalk24.default.green(`
|
|
32311
32800
|
Updated environment: ${response.environment.name}
|
|
32312
32801
|
`));
|
|
32313
32802
|
}
|
|
@@ -32322,20 +32811,20 @@ async function environmentDeleteCommand(idOrName, options) {
|
|
|
32322
32811
|
initial: false
|
|
32323
32812
|
});
|
|
32324
32813
|
if (!r.confirm) {
|
|
32325
|
-
console.log(
|
|
32814
|
+
console.log(import_chalk24.default.yellow("\nCancelled."));
|
|
32326
32815
|
return;
|
|
32327
32816
|
}
|
|
32328
32817
|
}
|
|
32329
32818
|
await orgAuthenticatedFetch(`/v1/environments/${id}`, { method: "DELETE" });
|
|
32330
|
-
console.log(
|
|
32819
|
+
console.log(import_chalk24.default.green(`
|
|
32331
32820
|
Deleted environment ${idOrName}.
|
|
32332
32821
|
`));
|
|
32333
32822
|
}
|
|
32334
32823
|
function printVariable(v, reveal) {
|
|
32335
|
-
console.log(
|
|
32336
|
-
console.log(
|
|
32337
|
-
console.log(
|
|
32338
|
-
console.log(
|
|
32824
|
+
console.log(import_chalk24.default.white(` ${v.key}`));
|
|
32825
|
+
console.log(import_chalk24.default.gray(` ID: ${v.id}`));
|
|
32826
|
+
console.log(import_chalk24.default.gray(` Value: ${reveal ? v.value : maskValue(v.value)}`));
|
|
32827
|
+
console.log(import_chalk24.default.gray(` Updated: ${formatDate2(v.updated_at)}`));
|
|
32339
32828
|
console.log();
|
|
32340
32829
|
}
|
|
32341
32830
|
async function envVarsListCommand(envIdOrName, options) {
|
|
@@ -32345,14 +32834,14 @@ async function envVarsListCommand(envIdOrName, options) {
|
|
|
32345
32834
|
`/v1/environments/${id}/variables`
|
|
32346
32835
|
);
|
|
32347
32836
|
if (response.environment_variables.length === 0) {
|
|
32348
|
-
console.log(
|
|
32837
|
+
console.log(import_chalk24.default.yellow("\nNo variables.\n"));
|
|
32349
32838
|
return;
|
|
32350
32839
|
}
|
|
32351
|
-
console.log(
|
|
32840
|
+
console.log(import_chalk24.default.green(`
|
|
32352
32841
|
Variables (${response.environment_variables.length}):
|
|
32353
32842
|
`));
|
|
32354
32843
|
if (!options.reveal) {
|
|
32355
|
-
console.log(
|
|
32844
|
+
console.log(import_chalk24.default.gray(" Values are masked. Pass --reveal to show full values.\n"));
|
|
32356
32845
|
}
|
|
32357
32846
|
for (const v of response.environment_variables) printVariable(v, !!options.reveal);
|
|
32358
32847
|
}
|
|
@@ -32369,7 +32858,7 @@ async function envVarsSetCommand(envIdOrName, key, value) {
|
|
|
32369
32858
|
`/v1/environments/${id}/variables/${match.id}`,
|
|
32370
32859
|
{ method: "PATCH", body: body2 }
|
|
32371
32860
|
);
|
|
32372
|
-
console.log(
|
|
32861
|
+
console.log(import_chalk24.default.green(`
|
|
32373
32862
|
Updated variable ${response2.environment_variable.key}.
|
|
32374
32863
|
`));
|
|
32375
32864
|
return;
|
|
@@ -32383,7 +32872,7 @@ Updated variable ${response2.environment_variable.key}.
|
|
|
32383
32872
|
`/v1/environments/${id}/variables`,
|
|
32384
32873
|
{ method: "POST", body }
|
|
32385
32874
|
);
|
|
32386
|
-
console.log(
|
|
32875
|
+
console.log(import_chalk24.default.green(`
|
|
32387
32876
|
Created variable ${response.environment_variable.key}.
|
|
32388
32877
|
`));
|
|
32389
32878
|
}
|
|
@@ -32397,7 +32886,7 @@ async function envVarsDeleteCommand(envIdOrName, keyOrId, options) {
|
|
|
32397
32886
|
);
|
|
32398
32887
|
const match = existing.environment_variables.find((v) => v.key === keyOrId);
|
|
32399
32888
|
if (!match) {
|
|
32400
|
-
console.log(
|
|
32889
|
+
console.log(import_chalk24.default.red(`Variable not found: ${keyOrId}`));
|
|
32401
32890
|
process.exit(1);
|
|
32402
32891
|
}
|
|
32403
32892
|
variableId = match.id;
|
|
@@ -32410,23 +32899,23 @@ async function envVarsDeleteCommand(envIdOrName, keyOrId, options) {
|
|
|
32410
32899
|
initial: false
|
|
32411
32900
|
});
|
|
32412
32901
|
if (!r.confirm) {
|
|
32413
|
-
console.log(
|
|
32902
|
+
console.log(import_chalk24.default.yellow("\nCancelled."));
|
|
32414
32903
|
return;
|
|
32415
32904
|
}
|
|
32416
32905
|
}
|
|
32417
32906
|
await orgAuthenticatedFetch(`/v1/environments/${id}/variables/${variableId}`, {
|
|
32418
32907
|
method: "DELETE"
|
|
32419
32908
|
});
|
|
32420
|
-
console.log(
|
|
32909
|
+
console.log(import_chalk24.default.green(`
|
|
32421
32910
|
Deleted variable ${keyOrId}.
|
|
32422
32911
|
`));
|
|
32423
32912
|
}
|
|
32424
32913
|
function printFile(f) {
|
|
32425
|
-
console.log(
|
|
32426
|
-
console.log(
|
|
32427
|
-
console.log(
|
|
32428
|
-
console.log(
|
|
32429
|
-
console.log(
|
|
32914
|
+
console.log(import_chalk24.default.white(` ${f.path}`));
|
|
32915
|
+
console.log(import_chalk24.default.gray(` ID: ${f.id}`));
|
|
32916
|
+
console.log(import_chalk24.default.gray(` Name: ${f.name}`));
|
|
32917
|
+
console.log(import_chalk24.default.gray(` Size: ${f.content.length} bytes`));
|
|
32918
|
+
console.log(import_chalk24.default.gray(` Updated: ${formatDate2(f.updated_at)}`));
|
|
32430
32919
|
console.log();
|
|
32431
32920
|
}
|
|
32432
32921
|
async function envFilesListCommand(envIdOrName) {
|
|
@@ -32436,20 +32925,20 @@ async function envFilesListCommand(envIdOrName) {
|
|
|
32436
32925
|
`/v1/environments/${id}/files`
|
|
32437
32926
|
);
|
|
32438
32927
|
if (response.environment_files.length === 0) {
|
|
32439
|
-
console.log(
|
|
32928
|
+
console.log(import_chalk24.default.yellow("\nNo files.\n"));
|
|
32440
32929
|
return;
|
|
32441
32930
|
}
|
|
32442
|
-
console.log(
|
|
32931
|
+
console.log(import_chalk24.default.green(`
|
|
32443
32932
|
Files (${response.environment_files.length}):
|
|
32444
32933
|
`));
|
|
32445
32934
|
for (const f of response.environment_files) printFile(f);
|
|
32446
32935
|
}
|
|
32447
32936
|
function readFileContent(options) {
|
|
32448
32937
|
if (options.file) {
|
|
32449
|
-
if (!
|
|
32938
|
+
if (!import_fs6.default.existsSync(options.file)) {
|
|
32450
32939
|
throw new Error(`Local file not found: ${options.file}`);
|
|
32451
32940
|
}
|
|
32452
|
-
return
|
|
32941
|
+
return import_fs6.default.readFileSync(options.file, "utf-8");
|
|
32453
32942
|
}
|
|
32454
32943
|
if (options.content !== void 0) return options.content;
|
|
32455
32944
|
throw new Error('Pass either --content "..." or --file <local-path>');
|
|
@@ -32470,7 +32959,7 @@ async function envFilesSetCommand(envIdOrName, destinationPath, options) {
|
|
|
32470
32959
|
`/v1/environments/${id}/files/${match.id}`,
|
|
32471
32960
|
{ method: "PATCH", body: body2 }
|
|
32472
32961
|
);
|
|
32473
|
-
console.log(
|
|
32962
|
+
console.log(import_chalk24.default.green(`
|
|
32474
32963
|
Updated file ${response2.environment_file.path}.
|
|
32475
32964
|
`));
|
|
32476
32965
|
return;
|
|
@@ -32485,7 +32974,7 @@ Updated file ${response2.environment_file.path}.
|
|
|
32485
32974
|
`/v1/environments/${id}/files`,
|
|
32486
32975
|
{ method: "POST", body }
|
|
32487
32976
|
);
|
|
32488
|
-
console.log(
|
|
32977
|
+
console.log(import_chalk24.default.green(`
|
|
32489
32978
|
Created file ${response.environment_file.path}.
|
|
32490
32979
|
`));
|
|
32491
32980
|
}
|
|
@@ -32499,7 +32988,7 @@ async function envFilesDeleteCommand(envIdOrName, pathOrId, options) {
|
|
|
32499
32988
|
);
|
|
32500
32989
|
const match = existing.environment_files.find((f) => f.path === pathOrId);
|
|
32501
32990
|
if (!match) {
|
|
32502
|
-
console.log(
|
|
32991
|
+
console.log(import_chalk24.default.red(`File not found: ${pathOrId}`));
|
|
32503
32992
|
process.exit(1);
|
|
32504
32993
|
}
|
|
32505
32994
|
fileId = match.id;
|
|
@@ -32512,14 +33001,14 @@ async function envFilesDeleteCommand(envIdOrName, pathOrId, options) {
|
|
|
32512
33001
|
initial: false
|
|
32513
33002
|
});
|
|
32514
33003
|
if (!r.confirm) {
|
|
32515
|
-
console.log(
|
|
33004
|
+
console.log(import_chalk24.default.yellow("\nCancelled."));
|
|
32516
33005
|
return;
|
|
32517
33006
|
}
|
|
32518
33007
|
}
|
|
32519
33008
|
await orgAuthenticatedFetch(`/v1/environments/${id}/files/${fileId}`, {
|
|
32520
33009
|
method: "DELETE"
|
|
32521
33010
|
});
|
|
32522
|
-
console.log(
|
|
33011
|
+
console.log(import_chalk24.default.green(`
|
|
32523
33012
|
Deleted file ${pathOrId}.
|
|
32524
33013
|
`));
|
|
32525
33014
|
}
|
|
@@ -32528,16 +33017,16 @@ async function envHookGetCommand(envIdOrName, kind) {
|
|
|
32528
33017
|
const id = await resolveEnvironmentId(envIdOrName);
|
|
32529
33018
|
const hook = kind === "warm" ? (await orgAuthenticatedFetch(`/v1/environments/${id}/warm-hooks`)).warm_hook : (await orgAuthenticatedFetch(`/v1/environments/${id}/start-hooks`)).start_hook;
|
|
32530
33019
|
if (!hook) {
|
|
32531
|
-
console.log(
|
|
33020
|
+
console.log(import_chalk24.default.yellow(`
|
|
32532
33021
|
No ${kind} hook configured.
|
|
32533
33022
|
`));
|
|
32534
33023
|
return;
|
|
32535
33024
|
}
|
|
32536
|
-
console.log(
|
|
33025
|
+
console.log(import_chalk24.default.green(`
|
|
32537
33026
|
${kind === "warm" ? "Warm" : "Start"} hook (v${hook.version}, ${hook.is_active ? "active" : "inactive"}):
|
|
32538
33027
|
`));
|
|
32539
|
-
console.log(
|
|
32540
|
-
console.log(
|
|
33028
|
+
console.log(import_chalk24.default.gray(` ID: ${hook.id}`));
|
|
33029
|
+
console.log(import_chalk24.default.gray(` Created: ${formatDate2(hook.created_at)}
|
|
32541
33030
|
`));
|
|
32542
33031
|
console.log(hook.content);
|
|
32543
33032
|
console.log();
|
|
@@ -32552,7 +33041,7 @@ async function envHookSaveCommand(envIdOrName, options, kind) {
|
|
|
32552
33041
|
`/v1/environments/${id}/warm-hooks/save`,
|
|
32553
33042
|
{ method: "POST", body: body2 }
|
|
32554
33043
|
);
|
|
32555
|
-
console.log(
|
|
33044
|
+
console.log(import_chalk24.default.green(`
|
|
32556
33045
|
Saved warm hook v${response2.warm_hook.version}.
|
|
32557
33046
|
`));
|
|
32558
33047
|
return;
|
|
@@ -32562,7 +33051,7 @@ Saved warm hook v${response2.warm_hook.version}.
|
|
|
32562
33051
|
`/v1/environments/${id}/start-hooks/save`,
|
|
32563
33052
|
{ method: "POST", body }
|
|
32564
33053
|
);
|
|
32565
|
-
console.log(
|
|
33054
|
+
console.log(import_chalk24.default.green(response.start_hook ? `
|
|
32566
33055
|
Saved start hook v${response.start_hook.version}.
|
|
32567
33056
|
` : "\nCleared start hook.\n"));
|
|
32568
33057
|
}
|
|
@@ -32579,7 +33068,7 @@ async function envHookTestCommand(envIdOrName, options, kind) {
|
|
|
32579
33068
|
body: kind === "warm" ? { content, mode: options.save ? "save_test" : "test_only" } : { content },
|
|
32580
33069
|
onEvent: (event) => {
|
|
32581
33070
|
if (event.type === "progress" && event.message) {
|
|
32582
|
-
console.log(
|
|
33071
|
+
console.log(import_chalk24.default.gray(event.message));
|
|
32583
33072
|
} else if (event.type === "output" && event.output) {
|
|
32584
33073
|
process.stdout.write(event.output);
|
|
32585
33074
|
} else if (event.type === "complete") {
|
|
@@ -32592,23 +33081,23 @@ async function envHookTestCommand(envIdOrName, options, kind) {
|
|
|
32592
33081
|
}
|
|
32593
33082
|
);
|
|
32594
33083
|
if (errorMessage) {
|
|
32595
|
-
console.log(
|
|
33084
|
+
console.log(import_chalk24.default.red(`
|
|
32596
33085
|
${errorMessage}
|
|
32597
33086
|
`));
|
|
32598
33087
|
process.exit(1);
|
|
32599
33088
|
}
|
|
32600
33089
|
if (timedOut) {
|
|
32601
|
-
console.log(
|
|
33090
|
+
console.log(import_chalk24.default.yellow(`
|
|
32602
33091
|
${kind === "warm" ? "Warm" : "Start"} hook timed out.
|
|
32603
33092
|
`));
|
|
32604
33093
|
process.exit(1);
|
|
32605
33094
|
}
|
|
32606
33095
|
if (exitCode === 0) {
|
|
32607
|
-
console.log(
|
|
33096
|
+
console.log(import_chalk24.default.green(`
|
|
32608
33097
|
${kind === "warm" ? "Warm" : "Start"} hook passed${options.save ? " and was saved" : ""} (exit code ${exitCode}).
|
|
32609
33098
|
`));
|
|
32610
33099
|
} else {
|
|
32611
|
-
console.log(
|
|
33100
|
+
console.log(import_chalk24.default.red(`
|
|
32612
33101
|
${kind === "warm" ? "Warm" : "Start"} hook failed (exit code ${exitCode ?? "unknown"}).
|
|
32613
33102
|
`));
|
|
32614
33103
|
process.exit(1);
|
|
@@ -32623,24 +33112,24 @@ async function envHookRepositoryHooksCommand(envIdOrName, kind) {
|
|
|
32623
33112
|
`/v1/environments/${id}/start-hooks/repository-hooks`
|
|
32624
33113
|
)).repositories.map((repository) => ({ ...repository, hook: repository.start_hook }));
|
|
32625
33114
|
if (repositories.length === 0) {
|
|
32626
|
-
console.log(
|
|
33115
|
+
console.log(import_chalk24.default.yellow("\nNo repositories bound to this environment.\n"));
|
|
32627
33116
|
return;
|
|
32628
33117
|
}
|
|
32629
|
-
console.log(
|
|
33118
|
+
console.log(import_chalk24.default.green(`
|
|
32630
33119
|
Repository ${kind} hooks (${repositories.length}):
|
|
32631
33120
|
`));
|
|
32632
33121
|
for (const repo of repositories) {
|
|
32633
|
-
console.log(
|
|
33122
|
+
console.log(import_chalk24.default.white(` ${repo.repository_name} @${repo.default_branch}`));
|
|
32634
33123
|
if (repo.error) {
|
|
32635
|
-
console.log(
|
|
33124
|
+
console.log(import_chalk24.default.red(` Error: ${repo.error}`));
|
|
32636
33125
|
} else if (repo.hook) {
|
|
32637
|
-
console.log(
|
|
32638
|
-
console.log(
|
|
33126
|
+
console.log(import_chalk24.default.gray(` Source: ${repo.filename ?? "(unknown)"}`));
|
|
33127
|
+
console.log(import_chalk24.default.gray(` Commands (${repo.hook.commands.length}):`));
|
|
32639
33128
|
for (const cmd of repo.hook.commands) {
|
|
32640
|
-
console.log(
|
|
33129
|
+
console.log(import_chalk24.default.gray(` ${cmd}`));
|
|
32641
33130
|
}
|
|
32642
33131
|
} else {
|
|
32643
|
-
console.log(
|
|
33132
|
+
console.log(import_chalk24.default.gray(` No ${kind}Hook defined.`));
|
|
32644
33133
|
}
|
|
32645
33134
|
console.log();
|
|
32646
33135
|
}
|
|
@@ -32705,7 +33194,7 @@ program.hook("preAction", async (_command, actionCommand) => {
|
|
|
32705
33194
|
throw new Error('No organization selected. Run "replicas org switch" to select one.');
|
|
32706
33195
|
}
|
|
32707
33196
|
} catch (error51) {
|
|
32708
|
-
console.error(
|
|
33197
|
+
console.error(import_chalk25.default.red(`
|
|
32709
33198
|
\u2717 ${error51 instanceof Error ? error51.message : "Unknown error"}
|
|
32710
33199
|
`));
|
|
32711
33200
|
process.exit(1);
|
|
@@ -32719,7 +33208,7 @@ function registerSlackCommands(parent) {
|
|
|
32719
33208
|
await slackThreadAttachCommand(options);
|
|
32720
33209
|
} catch (error51) {
|
|
32721
33210
|
if (error51 instanceof Error) {
|
|
32722
|
-
console.error(
|
|
33211
|
+
console.error(import_chalk25.default.red(`
|
|
32723
33212
|
\u2717 ${error51.message}
|
|
32724
33213
|
`));
|
|
32725
33214
|
}
|
|
@@ -32731,7 +33220,7 @@ function registerSlackCommands(parent) {
|
|
|
32731
33220
|
await slackThreadSwitchCommand(workspace, options);
|
|
32732
33221
|
} catch (error51) {
|
|
32733
33222
|
if (error51 instanceof Error) {
|
|
32734
|
-
console.error(
|
|
33223
|
+
console.error(import_chalk25.default.red(`
|
|
32735
33224
|
\u2717 ${error51.message}
|
|
32736
33225
|
`));
|
|
32737
33226
|
}
|
|
@@ -32745,7 +33234,7 @@ program.command("login").description("Authenticate with your Replicas account").
|
|
|
32745
33234
|
await loginCommand();
|
|
32746
33235
|
} catch (error51) {
|
|
32747
33236
|
if (error51 instanceof Error) {
|
|
32748
|
-
console.error(
|
|
33237
|
+
console.error(import_chalk25.default.red(`
|
|
32749
33238
|
\u2717 ${error51.message}
|
|
32750
33239
|
`));
|
|
32751
33240
|
}
|
|
@@ -32757,7 +33246,7 @@ program.command("init").description("Create a replicas.json or replicas.yaml con
|
|
|
32757
33246
|
initCommand(options);
|
|
32758
33247
|
} catch (error51) {
|
|
32759
33248
|
if (error51 instanceof Error) {
|
|
32760
|
-
console.error(
|
|
33249
|
+
console.error(import_chalk25.default.red(`
|
|
32761
33250
|
\u2717 ${error51.message}
|
|
32762
33251
|
`));
|
|
32763
33252
|
}
|
|
@@ -32769,7 +33258,7 @@ program.command("logout").description("Clear stored credentials").action(() => {
|
|
|
32769
33258
|
logoutCommand();
|
|
32770
33259
|
} catch (error51) {
|
|
32771
33260
|
if (error51 instanceof Error) {
|
|
32772
|
-
console.error(
|
|
33261
|
+
console.error(import_chalk25.default.red(`
|
|
32773
33262
|
\u2717 ${error51.message}
|
|
32774
33263
|
`));
|
|
32775
33264
|
}
|
|
@@ -32780,7 +33269,7 @@ program.command("muse-auth").description("Connect your Muse Code subscription to
|
|
|
32780
33269
|
try {
|
|
32781
33270
|
await museAuthCommand(options);
|
|
32782
33271
|
} catch (error51) {
|
|
32783
|
-
if (error51 instanceof Error) console.error(
|
|
33272
|
+
if (error51 instanceof Error) console.error(import_chalk25.default.red(`
|
|
32784
33273
|
\u2717 ${error51.message}
|
|
32785
33274
|
`));
|
|
32786
33275
|
process.exit(1);
|
|
@@ -32791,7 +33280,7 @@ program.command("whoami").description("Display current authenticated user").acti
|
|
|
32791
33280
|
await whoamiCommand();
|
|
32792
33281
|
} catch (error51) {
|
|
32793
33282
|
if (error51 instanceof Error) {
|
|
32794
|
-
console.error(
|
|
33283
|
+
console.error(import_chalk25.default.red(`
|
|
32795
33284
|
\u2717 ${error51.message}
|
|
32796
33285
|
`));
|
|
32797
33286
|
}
|
|
@@ -32803,7 +33292,7 @@ program.command("codex-auth").description("Connect your Codex credentials to Rep
|
|
|
32803
33292
|
await codexAuthCommand(options);
|
|
32804
33293
|
} catch (error51) {
|
|
32805
33294
|
if (error51 instanceof Error) {
|
|
32806
|
-
console.error(
|
|
33295
|
+
console.error(import_chalk25.default.red(`
|
|
32807
33296
|
\u2717 ${error51.message}
|
|
32808
33297
|
`));
|
|
32809
33298
|
}
|
|
@@ -32815,7 +33304,7 @@ program.command("claude-auth").description("Connect your Claude Code credentials
|
|
|
32815
33304
|
await claudeAuthCommand(options);
|
|
32816
33305
|
} catch (error51) {
|
|
32817
33306
|
if (error51 instanceof Error) {
|
|
32818
|
-
console.error(
|
|
33307
|
+
console.error(import_chalk25.default.red(`
|
|
32819
33308
|
\u2717 ${error51.message}
|
|
32820
33309
|
`));
|
|
32821
33310
|
}
|
|
@@ -32828,7 +33317,7 @@ org.command("switch").description("Switch to a different organization").action(a
|
|
|
32828
33317
|
await orgSwitchCommand();
|
|
32829
33318
|
} catch (error51) {
|
|
32830
33319
|
if (error51 instanceof Error) {
|
|
32831
|
-
console.error(
|
|
33320
|
+
console.error(import_chalk25.default.red(`
|
|
32832
33321
|
\u2717 ${error51.message}
|
|
32833
33322
|
`));
|
|
32834
33323
|
}
|
|
@@ -32840,7 +33329,7 @@ org.action(async () => {
|
|
|
32840
33329
|
await orgCommand();
|
|
32841
33330
|
} catch (error51) {
|
|
32842
33331
|
if (error51 instanceof Error) {
|
|
32843
|
-
console.error(
|
|
33332
|
+
console.error(import_chalk25.default.red(`
|
|
32844
33333
|
\u2717 ${error51.message}
|
|
32845
33334
|
`));
|
|
32846
33335
|
}
|
|
@@ -32852,7 +33341,7 @@ program.command("connect <workspace-name...>").description("Connect to a workspa
|
|
|
32852
33341
|
await connectCommand(workspaceName.join(" "));
|
|
32853
33342
|
} catch (error51) {
|
|
32854
33343
|
if (error51 instanceof Error) {
|
|
32855
|
-
console.error(
|
|
33344
|
+
console.error(import_chalk25.default.red(`
|
|
32856
33345
|
\u2717 ${error51.message}
|
|
32857
33346
|
`));
|
|
32858
33347
|
}
|
|
@@ -32863,7 +33352,7 @@ program.command("tunnel <workspace-name...>").description("Forward a workspace p
|
|
|
32863
33352
|
try {
|
|
32864
33353
|
await tunnelCommand(workspaceName.join(" "), options);
|
|
32865
33354
|
} catch (error51) {
|
|
32866
|
-
console.error(
|
|
33355
|
+
console.error(import_chalk25.default.red(`
|
|
32867
33356
|
Error: ${error51 instanceof Error ? error51.message : "Unknown error"}`));
|
|
32868
33357
|
process.exit(1);
|
|
32869
33358
|
}
|
|
@@ -32873,7 +33362,7 @@ program.command("code [workspace-name...]").description("Open a workspace in VSC
|
|
|
32873
33362
|
await codeCommand(workspaceName.join(" "));
|
|
32874
33363
|
} catch (error51) {
|
|
32875
33364
|
if (error51 instanceof Error) {
|
|
32876
|
-
console.error(
|
|
33365
|
+
console.error(import_chalk25.default.red(`
|
|
32877
33366
|
\u2717 ${error51.message}
|
|
32878
33367
|
`));
|
|
32879
33368
|
}
|
|
@@ -32886,7 +33375,7 @@ config2.command("get <key>").description("Get a configuration value").action(asy
|
|
|
32886
33375
|
await configGetCommand(key);
|
|
32887
33376
|
} catch (error51) {
|
|
32888
33377
|
if (error51 instanceof Error) {
|
|
32889
|
-
console.error(
|
|
33378
|
+
console.error(import_chalk25.default.red(`
|
|
32890
33379
|
\u2717 ${error51.message}
|
|
32891
33380
|
`));
|
|
32892
33381
|
}
|
|
@@ -32898,7 +33387,7 @@ config2.command("set <key> <value>").description("Set a configuration value").ac
|
|
|
32898
33387
|
await configSetCommand(key, value);
|
|
32899
33388
|
} catch (error51) {
|
|
32900
33389
|
if (error51 instanceof Error) {
|
|
32901
|
-
console.error(
|
|
33390
|
+
console.error(import_chalk25.default.red(`
|
|
32902
33391
|
\u2717 ${error51.message}
|
|
32903
33392
|
`));
|
|
32904
33393
|
}
|
|
@@ -32910,7 +33399,7 @@ config2.command("list").description("List all configuration values").action(asyn
|
|
|
32910
33399
|
await configListCommand();
|
|
32911
33400
|
} catch (error51) {
|
|
32912
33401
|
if (error51 instanceof Error) {
|
|
32913
|
-
console.error(
|
|
33402
|
+
console.error(import_chalk25.default.red(`
|
|
32914
33403
|
\u2717 ${error51.message}
|
|
32915
33404
|
`));
|
|
32916
33405
|
}
|
|
@@ -32922,7 +33411,7 @@ program.command("list").description("List all replicas").option("-p, --page <pag
|
|
|
32922
33411
|
await replicaListCommand(options);
|
|
32923
33412
|
} catch (error51) {
|
|
32924
33413
|
if (error51 instanceof Error) {
|
|
32925
|
-
console.error(
|
|
33414
|
+
console.error(import_chalk25.default.red(`
|
|
32926
33415
|
\u2717 ${error51.message}
|
|
32927
33416
|
`));
|
|
32928
33417
|
}
|
|
@@ -32934,7 +33423,7 @@ program.command("get <id>").description("Get replica details by ID").action(asyn
|
|
|
32934
33423
|
await replicaGetCommand(id);
|
|
32935
33424
|
} catch (error51) {
|
|
32936
33425
|
if (error51 instanceof Error) {
|
|
32937
|
-
console.error(
|
|
33426
|
+
console.error(import_chalk25.default.red(`
|
|
32938
33427
|
\u2717 ${error51.message}
|
|
32939
33428
|
`));
|
|
32940
33429
|
}
|
|
@@ -32946,7 +33435,7 @@ program.command("create [name]").description("Create a new replica").option("-m,
|
|
|
32946
33435
|
await replicaCreateCommand(name, options);
|
|
32947
33436
|
} catch (error51) {
|
|
32948
33437
|
if (error51 instanceof Error) {
|
|
32949
|
-
console.error(
|
|
33438
|
+
console.error(import_chalk25.default.red(`
|
|
32950
33439
|
\u2717 ${error51.message}
|
|
32951
33440
|
`));
|
|
32952
33441
|
}
|
|
@@ -32958,7 +33447,7 @@ program.command("send <id>").description("Send a message to a replica").option("
|
|
|
32958
33447
|
await replicaSendCommand(id, options);
|
|
32959
33448
|
} catch (error51) {
|
|
32960
33449
|
if (error51 instanceof Error) {
|
|
32961
|
-
console.error(
|
|
33450
|
+
console.error(import_chalk25.default.red(`
|
|
32962
33451
|
\u2717 ${error51.message}
|
|
32963
33452
|
`));
|
|
32964
33453
|
}
|
|
@@ -32970,7 +33459,7 @@ program.command("delete <id>").description("Delete a replica").option("-f, --for
|
|
|
32970
33459
|
await replicaDeleteCommand(id, options);
|
|
32971
33460
|
} catch (error51) {
|
|
32972
33461
|
if (error51 instanceof Error) {
|
|
32973
|
-
console.error(
|
|
33462
|
+
console.error(import_chalk25.default.red(`
|
|
32974
33463
|
\u2717 ${error51.message}
|
|
32975
33464
|
`));
|
|
32976
33465
|
}
|
|
@@ -32982,7 +33471,7 @@ program.command("read <id>").description("Read conversation history of a replica
|
|
|
32982
33471
|
await replicaReadCommand(id, options);
|
|
32983
33472
|
} catch (error51) {
|
|
32984
33473
|
if (error51 instanceof Error) {
|
|
32985
|
-
console.error(
|
|
33474
|
+
console.error(import_chalk25.default.red(`
|
|
32986
33475
|
\u2717 ${error51.message}
|
|
32987
33476
|
`));
|
|
32988
33477
|
}
|
|
@@ -32995,7 +33484,7 @@ automation.command("list").description("List all automations").option("-p, --pag
|
|
|
32995
33484
|
await automationListCommand(options);
|
|
32996
33485
|
} catch (error51) {
|
|
32997
33486
|
if (error51 instanceof Error) {
|
|
32998
|
-
console.error(
|
|
33487
|
+
console.error(import_chalk25.default.red(`
|
|
32999
33488
|
\u2717 ${error51.message}
|
|
33000
33489
|
`));
|
|
33001
33490
|
}
|
|
@@ -33007,7 +33496,7 @@ automation.command("get <id>").description("Get automation details by ID").actio
|
|
|
33007
33496
|
await automationGetCommand(id);
|
|
33008
33497
|
} catch (error51) {
|
|
33009
33498
|
if (error51 instanceof Error) {
|
|
33010
|
-
console.error(
|
|
33499
|
+
console.error(import_chalk25.default.red(`
|
|
33011
33500
|
\u2717 ${error51.message}
|
|
33012
33501
|
`));
|
|
33013
33502
|
}
|
|
@@ -33022,7 +33511,7 @@ automation.command("create [name]").description("Create a new automation").optio
|
|
|
33022
33511
|
});
|
|
33023
33512
|
} catch (error51) {
|
|
33024
33513
|
if (error51 instanceof Error) {
|
|
33025
|
-
console.error(
|
|
33514
|
+
console.error(import_chalk25.default.red(`
|
|
33026
33515
|
\u2717 ${error51.message}
|
|
33027
33516
|
`));
|
|
33028
33517
|
}
|
|
@@ -33034,7 +33523,7 @@ automation.command("edit <id>").description("Edit an existing automation").optio
|
|
|
33034
33523
|
await automationEditCommand(id, options);
|
|
33035
33524
|
} catch (error51) {
|
|
33036
33525
|
if (error51 instanceof Error) {
|
|
33037
|
-
console.error(
|
|
33526
|
+
console.error(import_chalk25.default.red(`
|
|
33038
33527
|
\u2717 ${error51.message}
|
|
33039
33528
|
`));
|
|
33040
33529
|
}
|
|
@@ -33046,7 +33535,7 @@ automation.command("run <id>").description("Manually trigger an automation (cron
|
|
|
33046
33535
|
await automationRunCommand(id);
|
|
33047
33536
|
} catch (error51) {
|
|
33048
33537
|
if (error51 instanceof Error) {
|
|
33049
|
-
console.error(
|
|
33538
|
+
console.error(import_chalk25.default.red(`
|
|
33050
33539
|
\u2717 ${error51.message}
|
|
33051
33540
|
`));
|
|
33052
33541
|
}
|
|
@@ -33058,7 +33547,7 @@ automation.command("delete <id>").description("Delete an automation").option("-f
|
|
|
33058
33547
|
await automationDeleteCommand(id, options);
|
|
33059
33548
|
} catch (error51) {
|
|
33060
33549
|
if (error51 instanceof Error) {
|
|
33061
|
-
console.error(
|
|
33550
|
+
console.error(import_chalk25.default.red(`
|
|
33062
33551
|
\u2717 ${error51.message}
|
|
33063
33552
|
`));
|
|
33064
33553
|
}
|
|
@@ -33070,7 +33559,7 @@ automation.command("check <checkRunId>").description("Report this automation run
|
|
|
33070
33559
|
await automationCheckCommand(checkRunId, options);
|
|
33071
33560
|
} catch (error51) {
|
|
33072
33561
|
if (error51 instanceof Error) {
|
|
33073
|
-
console.error(
|
|
33562
|
+
console.error(import_chalk25.default.red(`
|
|
33074
33563
|
\u2717 ${error51.message}
|
|
33075
33564
|
`));
|
|
33076
33565
|
}
|
|
@@ -33082,7 +33571,7 @@ automation.action(async () => {
|
|
|
33082
33571
|
await automationListCommand({});
|
|
33083
33572
|
} catch (error51) {
|
|
33084
33573
|
if (error51 instanceof Error) {
|
|
33085
|
-
console.error(
|
|
33574
|
+
console.error(import_chalk25.default.red(`
|
|
33086
33575
|
\u2717 ${error51.message}
|
|
33087
33576
|
`));
|
|
33088
33577
|
}
|
|
@@ -33095,7 +33584,7 @@ repos.command("list").description("List all repositories").action(async () => {
|
|
|
33095
33584
|
await repositoriesListCommand();
|
|
33096
33585
|
} catch (error51) {
|
|
33097
33586
|
if (error51 instanceof Error) {
|
|
33098
|
-
console.error(
|
|
33587
|
+
console.error(import_chalk25.default.red(`
|
|
33099
33588
|
\u2717 ${error51.message}
|
|
33100
33589
|
`));
|
|
33101
33590
|
}
|
|
@@ -33107,7 +33596,7 @@ repos.action(async () => {
|
|
|
33107
33596
|
await repositoriesListCommand();
|
|
33108
33597
|
} catch (error51) {
|
|
33109
33598
|
if (error51 instanceof Error) {
|
|
33110
|
-
console.error(
|
|
33599
|
+
console.error(import_chalk25.default.red(`
|
|
33111
33600
|
\u2717 ${error51.message}
|
|
33112
33601
|
`));
|
|
33113
33602
|
}
|
|
@@ -33120,7 +33609,7 @@ environment.command("list").description("List all environments").action(async ()
|
|
|
33120
33609
|
await environmentListCommand();
|
|
33121
33610
|
} catch (error51) {
|
|
33122
33611
|
if (error51 instanceof Error) {
|
|
33123
|
-
console.error(
|
|
33612
|
+
console.error(import_chalk25.default.red(`
|
|
33124
33613
|
\u2717 ${error51.message}
|
|
33125
33614
|
`));
|
|
33126
33615
|
}
|
|
@@ -33132,7 +33621,7 @@ environment.command("get <id-or-name>").description('Get an environment by ID or
|
|
|
33132
33621
|
await environmentGetCommand(idOrName);
|
|
33133
33622
|
} catch (error51) {
|
|
33134
33623
|
if (error51 instanceof Error) {
|
|
33135
|
-
console.error(
|
|
33624
|
+
console.error(import_chalk25.default.red(`
|
|
33136
33625
|
\u2717 ${error51.message}
|
|
33137
33626
|
`));
|
|
33138
33627
|
}
|
|
@@ -33144,7 +33633,7 @@ environment.command("create [name]").description("Create a new environment").opt
|
|
|
33144
33633
|
await environmentCreateCommand(name, options);
|
|
33145
33634
|
} catch (error51) {
|
|
33146
33635
|
if (error51 instanceof Error) {
|
|
33147
|
-
console.error(
|
|
33636
|
+
console.error(import_chalk25.default.red(`
|
|
33148
33637
|
\u2717 ${error51.message}
|
|
33149
33638
|
`));
|
|
33150
33639
|
}
|
|
@@ -33156,7 +33645,7 @@ environment.command("edit <id-or-name>").description("Edit an environment").opti
|
|
|
33156
33645
|
await environmentEditCommand(idOrName, options);
|
|
33157
33646
|
} catch (error51) {
|
|
33158
33647
|
if (error51 instanceof Error) {
|
|
33159
|
-
console.error(
|
|
33648
|
+
console.error(import_chalk25.default.red(`
|
|
33160
33649
|
\u2717 ${error51.message}
|
|
33161
33650
|
`));
|
|
33162
33651
|
}
|
|
@@ -33168,7 +33657,7 @@ environment.command("delete <id-or-name>").description("Delete an environment").
|
|
|
33168
33657
|
await environmentDeleteCommand(idOrName, options);
|
|
33169
33658
|
} catch (error51) {
|
|
33170
33659
|
if (error51 instanceof Error) {
|
|
33171
|
-
console.error(
|
|
33660
|
+
console.error(import_chalk25.default.red(`
|
|
33172
33661
|
\u2717 ${error51.message}
|
|
33173
33662
|
`));
|
|
33174
33663
|
}
|
|
@@ -33181,7 +33670,7 @@ envVars.command("list <env>").description("List variables in an environment (val
|
|
|
33181
33670
|
await envVarsListCommand(env, options);
|
|
33182
33671
|
} catch (error51) {
|
|
33183
33672
|
if (error51 instanceof Error) {
|
|
33184
|
-
console.error(
|
|
33673
|
+
console.error(import_chalk25.default.red(`
|
|
33185
33674
|
\u2717 ${error51.message}
|
|
33186
33675
|
`));
|
|
33187
33676
|
}
|
|
@@ -33193,7 +33682,7 @@ envVars.command("set <env> <key> <value>").description("Create or update a varia
|
|
|
33193
33682
|
await envVarsSetCommand(env, key, value);
|
|
33194
33683
|
} catch (error51) {
|
|
33195
33684
|
if (error51 instanceof Error) {
|
|
33196
|
-
console.error(
|
|
33685
|
+
console.error(import_chalk25.default.red(`
|
|
33197
33686
|
\u2717 ${error51.message}
|
|
33198
33687
|
`));
|
|
33199
33688
|
}
|
|
@@ -33205,7 +33694,7 @@ envVars.command("delete <env> <key-or-id>").description("Delete a variable by ke
|
|
|
33205
33694
|
await envVarsDeleteCommand(env, keyOrId, options);
|
|
33206
33695
|
} catch (error51) {
|
|
33207
33696
|
if (error51 instanceof Error) {
|
|
33208
|
-
console.error(
|
|
33697
|
+
console.error(import_chalk25.default.red(`
|
|
33209
33698
|
\u2717 ${error51.message}
|
|
33210
33699
|
`));
|
|
33211
33700
|
}
|
|
@@ -33218,7 +33707,7 @@ envFiles.command("list <env>").description("List files in an environment").actio
|
|
|
33218
33707
|
await envFilesListCommand(env);
|
|
33219
33708
|
} catch (error51) {
|
|
33220
33709
|
if (error51 instanceof Error) {
|
|
33221
|
-
console.error(
|
|
33710
|
+
console.error(import_chalk25.default.red(`
|
|
33222
33711
|
\u2717 ${error51.message}
|
|
33223
33712
|
`));
|
|
33224
33713
|
}
|
|
@@ -33230,7 +33719,7 @@ envFiles.command("set <env> <destination-path>").description("Create or update a
|
|
|
33230
33719
|
await envFilesSetCommand(env, destinationPath, options);
|
|
33231
33720
|
} catch (error51) {
|
|
33232
33721
|
if (error51 instanceof Error) {
|
|
33233
|
-
console.error(
|
|
33722
|
+
console.error(import_chalk25.default.red(`
|
|
33234
33723
|
\u2717 ${error51.message}
|
|
33235
33724
|
`));
|
|
33236
33725
|
}
|
|
@@ -33242,7 +33731,7 @@ envFiles.command("delete <env> <path-or-id>").description("Delete a file by dest
|
|
|
33242
33731
|
await envFilesDeleteCommand(env, pathOrId, options);
|
|
33243
33732
|
} catch (error51) {
|
|
33244
33733
|
if (error51 instanceof Error) {
|
|
33245
|
-
console.error(
|
|
33734
|
+
console.error(import_chalk25.default.red(`
|
|
33246
33735
|
\u2717 ${error51.message}
|
|
33247
33736
|
`));
|
|
33248
33737
|
}
|
|
@@ -33255,7 +33744,7 @@ function registerEnvironmentHookCommands(parent, config3) {
|
|
|
33255
33744
|
try {
|
|
33256
33745
|
await command();
|
|
33257
33746
|
} catch (error51) {
|
|
33258
|
-
if (error51 instanceof Error) console.error(
|
|
33747
|
+
if (error51 instanceof Error) console.error(import_chalk25.default.red(`
|
|
33259
33748
|
\u2717 ${error51.message}
|
|
33260
33749
|
`));
|
|
33261
33750
|
process.exit(1);
|
|
@@ -33291,7 +33780,7 @@ environment.action(async () => {
|
|
|
33291
33780
|
await environmentListCommand();
|
|
33292
33781
|
} catch (error51) {
|
|
33293
33782
|
if (error51 instanceof Error) {
|
|
33294
|
-
console.error(
|
|
33783
|
+
console.error(import_chalk25.default.red(`
|
|
33295
33784
|
\u2717 ${error51.message}
|
|
33296
33785
|
`));
|
|
33297
33786
|
}
|
|
@@ -33342,7 +33831,7 @@ if (isAgentMode()) {
|
|
|
33342
33831
|
await previewAddCommand(workspaceId, options);
|
|
33343
33832
|
} catch (error51) {
|
|
33344
33833
|
if (error51 instanceof Error) {
|
|
33345
|
-
console.error(
|
|
33834
|
+
console.error(import_chalk25.default.red(`
|
|
33346
33835
|
\u2717 ${error51.message}
|
|
33347
33836
|
`));
|
|
33348
33837
|
}
|
|
@@ -33354,7 +33843,7 @@ if (isAgentMode()) {
|
|
|
33354
33843
|
await previewListCommand(workspaceId);
|
|
33355
33844
|
} catch (error51) {
|
|
33356
33845
|
if (error51 instanceof Error) {
|
|
33357
|
-
console.error(
|
|
33846
|
+
console.error(import_chalk25.default.red(`
|
|
33358
33847
|
\u2717 ${error51.message}
|
|
33359
33848
|
`));
|
|
33360
33849
|
}
|
|
@@ -33366,7 +33855,7 @@ if (isAgentMode()) {
|
|
|
33366
33855
|
await previewRemoveCommand(workspaceId, options);
|
|
33367
33856
|
} catch (error51) {
|
|
33368
33857
|
if (error51 instanceof Error) {
|
|
33369
|
-
console.error(
|
|
33858
|
+
console.error(import_chalk25.default.red(`
|
|
33370
33859
|
\u2717 ${error51.message}
|
|
33371
33860
|
`));
|
|
33372
33861
|
}
|
|
@@ -33374,6 +33863,26 @@ if (isAgentMode()) {
|
|
|
33374
33863
|
}
|
|
33375
33864
|
});
|
|
33376
33865
|
}
|
|
33866
|
+
if (isEnvironmentSetupWorkspace()) {
|
|
33867
|
+
const environmentSetup = program.command("environment-setup").description("Report progress and propose configuration for an agent-led environment setup run");
|
|
33868
|
+
const runEnvironmentSetupCommand = (action) => async () => {
|
|
33869
|
+
try {
|
|
33870
|
+
await action();
|
|
33871
|
+
} catch (error51) {
|
|
33872
|
+
if (error51 instanceof Error) {
|
|
33873
|
+
console.error(import_chalk25.default.red(`
|
|
33874
|
+
\u2717 ${error51.message}
|
|
33875
|
+
`));
|
|
33876
|
+
}
|
|
33877
|
+
process.exit(1);
|
|
33878
|
+
}
|
|
33879
|
+
};
|
|
33880
|
+
environmentSetup.command("status").description("Show the setup run attached to this workspace").action(runEnvironmentSetupCommand(() => environmentSetupStatusCommand()));
|
|
33881
|
+
environmentSetup.command("step <key> <status>").description("Update a checklist step (understand | install | verify | configure | propose) to pending | in_progress | completed | skipped").action((key, status) => runEnvironmentSetupCommand(() => environmentSetupStepCommand(key, status))());
|
|
33882
|
+
environmentSetup.command("propose").description("Submit the proposed configuration for the user to review and save").requiredOption("-f, --file <path>", "Path to the proposal JSON file").action((options) => runEnvironmentSetupCommand(() => environmentSetupProposeCommand(options))());
|
|
33883
|
+
environmentSetup.command("request-variables").description("Ask the user for variables the app needs; returns immediately so you can keep working").requiredOption("-f, --file <path>", 'Path to a JSON file: { "variables": [{ "key", "description", "required" }] }').action((options) => runEnvironmentSetupCommand(() => environmentSetupRequestVariablesCommand(options))());
|
|
33884
|
+
environmentSetup.command("wait-variables").description("Wait until requested required variables are provided or skipped, then export them for new shells (default 5m)").option("-t, --timeout <duration>", "How long to wait, e.g. 90s or 5m (max 15m)").option("-k, --keys <keys>", "Comma-separated keys to wait for instead of every pending required key").action((options) => runEnvironmentSetupCommand(() => environmentSetupWaitVariablesCommand(options))());
|
|
33885
|
+
}
|
|
33377
33886
|
if (isAgentMode()) {
|
|
33378
33887
|
const identity = program.command("identity").description("Obtain short-lived workspace identity tokens (OIDC) for the services this workspace calls");
|
|
33379
33888
|
identity.command("token").description("Print a workspace token for an audience (defaults to replicas:workspace)").option("-a, --audience <audience>", "Audience (`aud`) the receiving service verifies, for example its URL").addOption(new import_commander.Option("--format <format>", "Output a raw token or Google executable credentials").choices(["text", "gcp"]).default("text")).action(identityTokenCommand);
|
|
@@ -33431,7 +33940,7 @@ if (isAgentMode()) {
|
|
|
33431
33940
|
await mediaUploadCommand(files, options);
|
|
33432
33941
|
} catch (error51) {
|
|
33433
33942
|
if (error51 instanceof Error) {
|
|
33434
|
-
console.error(
|
|
33943
|
+
console.error(import_chalk25.default.red(`
|
|
33435
33944
|
\u2717 ${error51.message}
|
|
33436
33945
|
`));
|
|
33437
33946
|
}
|
|
@@ -33442,7 +33951,7 @@ if (isAgentMode()) {
|
|
|
33442
33951
|
try {
|
|
33443
33952
|
await mediaShareCommand(mediaId);
|
|
33444
33953
|
} catch (error51) {
|
|
33445
|
-
if (error51 instanceof Error) console.error(
|
|
33954
|
+
if (error51 instanceof Error) console.error(import_chalk25.default.red(`
|
|
33446
33955
|
\u2717 ${error51.message}
|
|
33447
33956
|
`));
|
|
33448
33957
|
process.exit(1);
|
|
@@ -33452,7 +33961,7 @@ if (isAgentMode()) {
|
|
|
33452
33961
|
try {
|
|
33453
33962
|
await mediaRevokeCommand(mediaId);
|
|
33454
33963
|
} catch (error51) {
|
|
33455
|
-
if (error51 instanceof Error) console.error(
|
|
33964
|
+
if (error51 instanceof Error) console.error(import_chalk25.default.red(`
|
|
33456
33965
|
\u2717 ${error51.message}
|
|
33457
33966
|
`));
|
|
33458
33967
|
process.exit(1);
|
|
@@ -33462,7 +33971,7 @@ if (isAgentMode()) {
|
|
|
33462
33971
|
try {
|
|
33463
33972
|
await mediaDeleteCommand(mediaId);
|
|
33464
33973
|
} catch (error51) {
|
|
33465
|
-
if (error51 instanceof Error) console.error(
|
|
33974
|
+
if (error51 instanceof Error) console.error(import_chalk25.default.red(`
|
|
33466
33975
|
\u2717 ${error51.message}
|
|
33467
33976
|
`));
|
|
33468
33977
|
process.exit(1);
|
|
@@ -33473,7 +33982,7 @@ if (isAgentMode()) {
|
|
|
33473
33982
|
await mediaListCommand(options);
|
|
33474
33983
|
} catch (error51) {
|
|
33475
33984
|
if (error51 instanceof Error) {
|
|
33476
|
-
console.error(
|
|
33985
|
+
console.error(import_chalk25.default.red(`
|
|
33477
33986
|
\u2717 ${error51.message}
|
|
33478
33987
|
`));
|
|
33479
33988
|
}
|
|
@@ -33486,7 +33995,7 @@ if (isAgentMode()) {
|
|
|
33486
33995
|
await mothershipMonitorChannelCommand(options);
|
|
33487
33996
|
} catch (error51) {
|
|
33488
33997
|
if (error51 instanceof Error) {
|
|
33489
|
-
console.error(
|
|
33998
|
+
console.error(import_chalk25.default.red(`
|
|
33490
33999
|
\u2717 ${error51.message}
|
|
33491
34000
|
`));
|
|
33492
34001
|
}
|
|
@@ -33498,7 +34007,7 @@ if (isAgentMode()) {
|
|
|
33498
34007
|
await mothershipSpawnCommand(options);
|
|
33499
34008
|
} catch (error51) {
|
|
33500
34009
|
if (error51 instanceof Error) {
|
|
33501
|
-
console.error(
|
|
34010
|
+
console.error(import_chalk25.default.red(`
|
|
33502
34011
|
\u2717 ${error51.message}
|
|
33503
34012
|
`));
|
|
33504
34013
|
}
|
|
@@ -33510,7 +34019,7 @@ if (isAgentMode()) {
|
|
|
33510
34019
|
await mothershipRelayCommand(options);
|
|
33511
34020
|
} catch (error51) {
|
|
33512
34021
|
if (error51 instanceof Error) {
|
|
33513
|
-
console.error(
|
|
34022
|
+
console.error(import_chalk25.default.red(`
|
|
33514
34023
|
\u2717 ${error51.message}
|
|
33515
34024
|
`));
|
|
33516
34025
|
}
|
|
@@ -33532,6 +34041,7 @@ if (isAgentMode()) {
|
|
|
33532
34041
|
"automation",
|
|
33533
34042
|
"repos",
|
|
33534
34043
|
"environment",
|
|
34044
|
+
"environment-setup",
|
|
33535
34045
|
"mothership"
|
|
33536
34046
|
]);
|
|
33537
34047
|
const kept = program.commands.filter((cmd) => allowed.has(cmd.name()));
|
|
@@ -33543,7 +34053,7 @@ async function main() {
|
|
|
33543
34053
|
if (process.argv[2] === "computer" && isAgentMode()) {
|
|
33544
34054
|
const result = (0, import_node_child_process3.spawnSync)("replicas-computer", process.argv.slice(3), { stdio: "inherit" });
|
|
33545
34055
|
if (result.error) {
|
|
33546
|
-
console.error(
|
|
34056
|
+
console.error(import_chalk25.default.red(`
|
|
33547
34057
|
\u2717 replicas-computer is unavailable in this workspace image
|
|
33548
34058
|
`));
|
|
33549
34059
|
process.exitCode = 1;
|