replicas-cli 0.2.752 → 0.2.754
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 +1102 -594
- 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,10 +7362,10 @@ 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";
|
|
@@ -7376,6 +7376,7 @@ var WEB_APP_PATHS = {
|
|
|
7376
7376
|
home: "/",
|
|
7377
7377
|
onboarding: "/onboarding",
|
|
7378
7378
|
workspaces: "/workspace",
|
|
7379
|
+
environmentSetup: "/workspace/setup",
|
|
7379
7380
|
automations: "/automations",
|
|
7380
7381
|
environment: "/environment",
|
|
7381
7382
|
analytics: "/analytics",
|
|
@@ -7534,6 +7535,9 @@ function isAgentMode() {
|
|
|
7534
7535
|
return false;
|
|
7535
7536
|
}
|
|
7536
7537
|
}
|
|
7538
|
+
function isEnvironmentSetupWorkspace() {
|
|
7539
|
+
return isAgentMode() && !!process.env.REPLICAS_ENVIRONMENT_SETUP_RUN_ID;
|
|
7540
|
+
}
|
|
7537
7541
|
function readAgentConfig() {
|
|
7538
7542
|
if (!import_fs.default.existsSync(CONFIG_FILE)) {
|
|
7539
7543
|
return null;
|
|
@@ -7649,6 +7653,9 @@ var import_prompts3 = __toESM(require("prompts"));
|
|
|
7649
7653
|
function isRecord(value) {
|
|
7650
7654
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7651
7655
|
}
|
|
7656
|
+
function isNonEmptyString(value) {
|
|
7657
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
7658
|
+
}
|
|
7652
7659
|
|
|
7653
7660
|
// ../shared/src/json.ts
|
|
7654
7661
|
function safeJsonParse(str, fallback) {
|
|
@@ -8657,10 +8664,10 @@ function mergeDefs(...defs) {
|
|
|
8657
8664
|
function cloneDef(schema) {
|
|
8658
8665
|
return mergeDefs(schema._zod.def);
|
|
8659
8666
|
}
|
|
8660
|
-
function getElementAtPath(obj,
|
|
8661
|
-
if (!
|
|
8667
|
+
function getElementAtPath(obj, path7) {
|
|
8668
|
+
if (!path7)
|
|
8662
8669
|
return obj;
|
|
8663
|
-
return
|
|
8670
|
+
return path7.reduce((acc, key) => acc?.[key], obj);
|
|
8664
8671
|
}
|
|
8665
8672
|
function promiseAllObject(promisesObj) {
|
|
8666
8673
|
const keys = Object.keys(promisesObj);
|
|
@@ -9069,11 +9076,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
9069
9076
|
}
|
|
9070
9077
|
return false;
|
|
9071
9078
|
}
|
|
9072
|
-
function prefixIssues(
|
|
9079
|
+
function prefixIssues(path7, issues) {
|
|
9073
9080
|
return issues.map((iss) => {
|
|
9074
9081
|
var _a3;
|
|
9075
9082
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
9076
|
-
iss.path.unshift(
|
|
9083
|
+
iss.path.unshift(path7);
|
|
9077
9084
|
return iss;
|
|
9078
9085
|
});
|
|
9079
9086
|
}
|
|
@@ -9220,16 +9227,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
|
|
|
9220
9227
|
}
|
|
9221
9228
|
function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
9222
9229
|
const fieldErrors = { _errors: [] };
|
|
9223
|
-
const processError = (error52,
|
|
9230
|
+
const processError = (error52, path7 = []) => {
|
|
9224
9231
|
for (const issue2 of error52.issues) {
|
|
9225
9232
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
9226
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
9233
|
+
issue2.errors.map((issues) => processError({ issues }, [...path7, ...issue2.path]));
|
|
9227
9234
|
} else if (issue2.code === "invalid_key") {
|
|
9228
|
-
processError({ issues: issue2.issues }, [...
|
|
9235
|
+
processError({ issues: issue2.issues }, [...path7, ...issue2.path]);
|
|
9229
9236
|
} else if (issue2.code === "invalid_element") {
|
|
9230
|
-
processError({ issues: issue2.issues }, [...
|
|
9237
|
+
processError({ issues: issue2.issues }, [...path7, ...issue2.path]);
|
|
9231
9238
|
} else {
|
|
9232
|
-
const fullpath = [...
|
|
9239
|
+
const fullpath = [...path7, ...issue2.path];
|
|
9233
9240
|
if (fullpath.length === 0) {
|
|
9234
9241
|
fieldErrors._errors.push(mapper(issue2));
|
|
9235
9242
|
} else {
|
|
@@ -9256,17 +9263,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
|
9256
9263
|
}
|
|
9257
9264
|
function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
9258
9265
|
const result = { errors: [] };
|
|
9259
|
-
const processError = (error52,
|
|
9266
|
+
const processError = (error52, path7 = []) => {
|
|
9260
9267
|
var _a3, _b;
|
|
9261
9268
|
for (const issue2 of error52.issues) {
|
|
9262
9269
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
9263
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
9270
|
+
issue2.errors.map((issues) => processError({ issues }, [...path7, ...issue2.path]));
|
|
9264
9271
|
} else if (issue2.code === "invalid_key") {
|
|
9265
|
-
processError({ issues: issue2.issues }, [...
|
|
9272
|
+
processError({ issues: issue2.issues }, [...path7, ...issue2.path]);
|
|
9266
9273
|
} else if (issue2.code === "invalid_element") {
|
|
9267
|
-
processError({ issues: issue2.issues }, [...
|
|
9274
|
+
processError({ issues: issue2.issues }, [...path7, ...issue2.path]);
|
|
9268
9275
|
} else {
|
|
9269
|
-
const fullpath = [...
|
|
9276
|
+
const fullpath = [...path7, ...issue2.path];
|
|
9270
9277
|
if (fullpath.length === 0) {
|
|
9271
9278
|
result.errors.push(mapper(issue2));
|
|
9272
9279
|
continue;
|
|
@@ -9298,8 +9305,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
|
9298
9305
|
}
|
|
9299
9306
|
function toDotPath(_path) {
|
|
9300
9307
|
const segs = [];
|
|
9301
|
-
const
|
|
9302
|
-
for (const seg of
|
|
9308
|
+
const path7 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
9309
|
+
for (const seg of path7) {
|
|
9303
9310
|
if (typeof seg === "number")
|
|
9304
9311
|
segs.push(`[${seg}]`);
|
|
9305
9312
|
else if (typeof seg === "symbol")
|
|
@@ -21991,13 +21998,13 @@ function resolveRef(ref, ctx) {
|
|
|
21991
21998
|
if (!ref.startsWith("#")) {
|
|
21992
21999
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
21993
22000
|
}
|
|
21994
|
-
const
|
|
21995
|
-
if (
|
|
22001
|
+
const path7 = ref.slice(1).split("/").filter(Boolean);
|
|
22002
|
+
if (path7.length === 0) {
|
|
21996
22003
|
return ctx.rootSchema;
|
|
21997
22004
|
}
|
|
21998
22005
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
21999
|
-
if (
|
|
22000
|
-
const key =
|
|
22006
|
+
if (path7[0] === defsKey) {
|
|
22007
|
+
const key = path7[1];
|
|
22001
22008
|
if (!key || !ctx.defs[key]) {
|
|
22002
22009
|
throw new Error(`Reference not found: ${ref}`);
|
|
22003
22010
|
}
|
|
@@ -22755,7 +22762,7 @@ var CLAUDE_MODEL_MIN_SANDBOX_IMAGE = {
|
|
|
22755
22762
|
};
|
|
22756
22763
|
var CODEX_MODEL_MIN_SANDBOX_IMAGE = {
|
|
22757
22764
|
[GPT_6_ASTRA_MODEL]: "replicas-sandbox-2026-09-04-v7",
|
|
22758
|
-
[GPT_6_1_SOL_MODEL]: "replicas-sandbox-2026-09-
|
|
22765
|
+
[GPT_6_1_SOL_MODEL]: "replicas-sandbox-2026-09-30-v11",
|
|
22759
22766
|
[GPT_6_SOL_MODEL]: "replicas-sandbox-2026-09-24-v1",
|
|
22760
22767
|
[GPT_6_LUNA_MODEL]: "replicas-sandbox-2026-09-24-v1"
|
|
22761
22768
|
};
|
|
@@ -23206,11 +23213,11 @@ function parseShellScript(script, cwd) {
|
|
|
23206
23213
|
parseUntil(scope, 0, false);
|
|
23207
23214
|
return scope.commands;
|
|
23208
23215
|
}
|
|
23209
|
-
function resolveShellPath(dir,
|
|
23210
|
-
if (
|
|
23211
|
-
if (!
|
|
23216
|
+
function resolveShellPath(dir, path7) {
|
|
23217
|
+
if (path7.includes(SHELL_OPAQUE) || path7.startsWith("~")) return null;
|
|
23218
|
+
if (!path7.startsWith("/") && dir === null) return null;
|
|
23212
23219
|
const parts = [];
|
|
23213
|
-
for (const part of (
|
|
23220
|
+
for (const part of (path7.startsWith("/") ? path7 : `${dir}/${path7}`).split("/")) {
|
|
23214
23221
|
if (part === "..") parts.pop();
|
|
23215
23222
|
else if (part && part !== ".") parts.push(part);
|
|
23216
23223
|
}
|
|
@@ -23560,16 +23567,16 @@ function parseSkillName(tool, input) {
|
|
|
23560
23567
|
const skillName = parsedInput.skill ?? parsedInput.name;
|
|
23561
23568
|
return typeof skillName === "string" && skillName ? skillName : null;
|
|
23562
23569
|
}
|
|
23563
|
-
function skillNameFromFilePath(
|
|
23564
|
-
const skillName = skillNameFromSkillRootPath(
|
|
23570
|
+
function skillNameFromFilePath(path7) {
|
|
23571
|
+
const skillName = skillNameFromSkillRootPath(path7);
|
|
23565
23572
|
if (skillName) return skillName;
|
|
23566
|
-
const parts =
|
|
23573
|
+
const parts = path7.split(/[\\/]+/).filter(Boolean);
|
|
23567
23574
|
if (parts.length < 2 || parts[parts.length - 1].toLowerCase() !== "skill.md") return null;
|
|
23568
23575
|
const fallbackSkillName = parts[parts.length - 2];
|
|
23569
23576
|
return fallbackSkillName && fallbackSkillName.toLowerCase() !== "skills" ? fallbackSkillName : null;
|
|
23570
23577
|
}
|
|
23571
|
-
function skillNameFromSkillRootPath(
|
|
23572
|
-
const parts =
|
|
23578
|
+
function skillNameFromSkillRootPath(path7) {
|
|
23579
|
+
const parts = path7.split(/[\\/]+/).filter(Boolean);
|
|
23573
23580
|
const skillsIndex = parts.findLastIndex((part) => part.toLowerCase() === "skills");
|
|
23574
23581
|
if (skillsIndex === -1) return null;
|
|
23575
23582
|
const firstSkillPart = parts[skillsIndex + 1];
|
|
@@ -23579,9 +23586,9 @@ function skillNameFromSkillRootPath(path6) {
|
|
|
23579
23586
|
function parseSkillFilePath(input) {
|
|
23580
23587
|
const parsedInput = typeof input === "string" ? safeJsonParse(input, null) : input;
|
|
23581
23588
|
if (!isRecord(parsedInput)) return null;
|
|
23582
|
-
const
|
|
23583
|
-
if (!
|
|
23584
|
-
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);
|
|
23585
23592
|
}
|
|
23586
23593
|
function skillNameFromToolCall(tool, input) {
|
|
23587
23594
|
const directSkillName = parseSkillName(tool, input);
|
|
@@ -23893,8 +23900,451 @@ var DOCKER_ABILITY = {
|
|
|
23893
23900
|
referenceFile: { name: "DOCKER.md", content: REFERENCE2 }
|
|
23894
23901
|
};
|
|
23895
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
|
+
|
|
23896
24346
|
// ../shared/src/default-skills/replicas-agent/abilities/github.ts
|
|
23897
|
-
var
|
|
24347
|
+
var SECTION4 = `### GitHub
|
|
23898
24348
|
Use the pre-authenticated \`gh\` CLI for repository workflows and the workspace-scoped TypeScript SDK for GitHub API calls.
|
|
23899
24349
|
|
|
23900
24350
|
**Reference:** \`references/GITHUB.md\`
|
|
@@ -23904,7 +24354,7 @@ Use this when:
|
|
|
23904
24354
|
- You need to interact with GitHub issues or actions
|
|
23905
24355
|
- You need to use the GitHub API for advanced operations
|
|
23906
24356
|
- You need to include images in PR descriptions`;
|
|
23907
|
-
var
|
|
24357
|
+
var REFERENCE4 = `# GitHub Integration
|
|
23908
24358
|
|
|
23909
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.
|
|
23910
24360
|
|
|
@@ -24033,12 +24483,12 @@ var GITHUB_ABILITY = {
|
|
|
24033
24483
|
label: "GitHub",
|
|
24034
24484
|
description: "GitHub workflows through gh and API calls through @replicas/sdk.",
|
|
24035
24485
|
bullet: "- Interacting with GitHub (creating PRs, managing issues, using the API, etc.)",
|
|
24036
|
-
section:
|
|
24037
|
-
referenceFile: { name: "GITHUB.md", content:
|
|
24486
|
+
section: SECTION4,
|
|
24487
|
+
referenceFile: { name: "GITHUB.md", content: REFERENCE4 }
|
|
24038
24488
|
};
|
|
24039
24489
|
|
|
24040
24490
|
// ../shared/src/default-skills/replicas-agent/abilities/gitlab.ts
|
|
24041
|
-
var
|
|
24491
|
+
var SECTION5 = `### GitLab
|
|
24042
24492
|
Use plain git for repository traffic and the workspace-scoped TypeScript SDK for GitLab API operations.
|
|
24043
24493
|
|
|
24044
24494
|
**Reference:** \`references/GITLAB.md\`
|
|
@@ -24047,7 +24497,7 @@ Use this when:
|
|
|
24047
24497
|
- A repository remote is on gitlab.com or a self-managed GitLab instance
|
|
24048
24498
|
- You need to open or update a merge request
|
|
24049
24499
|
- You need GitLab issues, pipelines, comments, or other API data`;
|
|
24050
|
-
var
|
|
24500
|
+
var REFERENCE5 = `# GitLab Integration
|
|
24051
24501
|
|
|
24052
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.
|
|
24053
24503
|
|
|
@@ -24095,12 +24545,12 @@ var GITLAB_ABILITY = {
|
|
|
24095
24545
|
label: "GitLab",
|
|
24096
24546
|
description: "Git for repository traffic and @replicas/sdk for the GitLab API.",
|
|
24097
24547
|
bullet: "- Interacting with GitLab (pushing to GitLab repos, opening merge requests)",
|
|
24098
|
-
section:
|
|
24099
|
-
referenceFile: { name: "GITLAB.md", content:
|
|
24548
|
+
section: SECTION5,
|
|
24549
|
+
referenceFile: { name: "GITLAB.md", content: REFERENCE5 }
|
|
24100
24550
|
};
|
|
24101
24551
|
|
|
24102
24552
|
// ../shared/src/default-skills/replicas-agent/abilities/linear.ts
|
|
24103
|
-
var
|
|
24553
|
+
var SECTION6 = `### Linear
|
|
24104
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.
|
|
24105
24555
|
|
|
24106
24556
|
**Reference:** \`references/LINEAR.md\`
|
|
@@ -24111,7 +24561,7 @@ Use this when:
|
|
|
24111
24561
|
- You need to update an issue's state or add a comment
|
|
24112
24562
|
- You need to search Linear issues
|
|
24113
24563
|
- A Linear request failed with an authentication error`;
|
|
24114
|
-
var
|
|
24564
|
+
var REFERENCE6 = `# Linear Integration
|
|
24115
24565
|
|
|
24116
24566
|
Use \`@replicas/sdk\`; never request or handle a Linear OAuth token. Replicas refreshes the organization credential behind the gateway.
|
|
24117
24567
|
|
|
@@ -24200,12 +24650,12 @@ var LINEAR_ABILITY = {
|
|
|
24200
24650
|
label: "Linear",
|
|
24201
24651
|
description: "Create tickets, fetch issues, comment, and update state through @replicas/sdk.",
|
|
24202
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.",
|
|
24203
|
-
section:
|
|
24204
|
-
referenceFile: { name: "LINEAR.md", content:
|
|
24653
|
+
section: SECTION6,
|
|
24654
|
+
referenceFile: { name: "LINEAR.md", content: REFERENCE6 }
|
|
24205
24655
|
};
|
|
24206
24656
|
|
|
24207
24657
|
// ../shared/src/default-skills/replicas-agent/abilities/media.ts
|
|
24208
|
-
var
|
|
24658
|
+
var SECTION7 = `### Media
|
|
24209
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.
|
|
24210
24660
|
|
|
24211
24661
|
**Reference:** \`references/MEDIA.md\`
|
|
@@ -24216,7 +24666,7 @@ Use this when:
|
|
|
24216
24666
|
- You produce a self-contained HTML report that should be linked from a pull request
|
|
24217
24667
|
- You record video output (browser automation, screen capture) \u2014 including the recommended aspect ratio and FPS
|
|
24218
24668
|
- You need to embed media in a Slack/Linear/GitHub/GitLab message AND keep a referenceable copy in the Replicas dashboard`;
|
|
24219
|
-
var
|
|
24669
|
+
var REFERENCE7 = `# Media (Screenshots, Recordings, Audio, HTML)
|
|
24220
24670
|
|
|
24221
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).
|
|
24222
24672
|
|
|
@@ -24541,8 +24991,8 @@ var MEDIA_ABILITY = {
|
|
|
24541
24991
|
label: "Media",
|
|
24542
24992
|
description: "Deliver media to Replicas and destination workflows with inline uploads.",
|
|
24543
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",
|
|
24544
|
-
section:
|
|
24545
|
-
referenceFile: { name: "MEDIA.md", content:
|
|
24994
|
+
section: SECTION7,
|
|
24995
|
+
referenceFile: { name: "MEDIA.md", content: REFERENCE7 }
|
|
24546
24996
|
};
|
|
24547
24997
|
|
|
24548
24998
|
// ../shared/src/sandbox.ts
|
|
@@ -24590,7 +25040,7 @@ var memoryGenerationManifestSchema = external_exports.object({
|
|
|
24590
25040
|
});
|
|
24591
25041
|
|
|
24592
25042
|
// ../shared/src/default-skills/replicas-agent/abilities/memory.ts
|
|
24593
|
-
var
|
|
25043
|
+
var SECTION8 = `### Memory
|
|
24594
25044
|
Check relevant long-term memory before substantive work when historical context could improve the result.
|
|
24595
25045
|
|
|
24596
25046
|
**Reference:** \`references/MEMORY.md\`
|
|
@@ -24602,7 +25052,7 @@ Use this when:
|
|
|
24602
25052
|
- Related work may explain an error or implementation choice
|
|
24603
25053
|
|
|
24604
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.`;
|
|
24605
|
-
var
|
|
25055
|
+
var REFERENCE8 = `# Long-term memory
|
|
24606
25056
|
|
|
24607
25057
|
Replicas memory is installed under \`~/.replicas/memories\`:
|
|
24608
25058
|
|
|
@@ -24625,13 +25075,13 @@ var MEMORY_ABILITY = {
|
|
|
24625
25075
|
label: "Memory",
|
|
24626
25076
|
description: "Check private and organization memory before substantive work.",
|
|
24627
25077
|
bullet: "",
|
|
24628
|
-
section:
|
|
24629
|
-
referenceFile: { name: "MEMORY.md", content:
|
|
25078
|
+
section: SECTION8,
|
|
25079
|
+
referenceFile: { name: "MEMORY.md", content: REFERENCE8 },
|
|
24630
25080
|
locked: true
|
|
24631
25081
|
};
|
|
24632
25082
|
|
|
24633
25083
|
// ../shared/src/default-skills/replicas-agent/abilities/previews.ts
|
|
24634
|
-
var
|
|
25084
|
+
var SECTION9 = `### Previews
|
|
24635
25085
|
Expose locally running services (web apps, APIs, databases) as public preview URLs so humans can interact with them directly.
|
|
24636
25086
|
|
|
24637
25087
|
**Reference:** \`references/PREVIEWS.md\`
|
|
@@ -24640,7 +25090,7 @@ Use this when:
|
|
|
24640
25090
|
- You need to start a service that a human should view or interact with
|
|
24641
25091
|
- The task involves UI work that benefits from human review
|
|
24642
25092
|
- You are verifying frontend/backend integrations visually`;
|
|
24643
|
-
var
|
|
25093
|
+
var REFERENCE9 = `# Preview URLs
|
|
24644
25094
|
|
|
24645
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.
|
|
24646
25096
|
|
|
@@ -24716,12 +25166,12 @@ var PREVIEWS_ABILITY = {
|
|
|
24716
25166
|
label: "Previews",
|
|
24717
25167
|
description: "Expose locally running services on public preview URLs for humans.",
|
|
24718
25168
|
bullet: "- Creating preview URLs for locally running services",
|
|
24719
|
-
section:
|
|
24720
|
-
referenceFile: { name: "PREVIEWS.md", content:
|
|
25169
|
+
section: SECTION9,
|
|
25170
|
+
referenceFile: { name: "PREVIEWS.md", content: REFERENCE9 }
|
|
24721
25171
|
};
|
|
24722
25172
|
|
|
24723
25173
|
// ../shared/src/default-skills/replicas-agent/abilities/plugins.ts
|
|
24724
|
-
var
|
|
25174
|
+
var SECTION10 = `### Plugins
|
|
24725
25175
|
Discover and execute installed marketplace tools through the workspace-scoped TypeScript SDK.
|
|
24726
25176
|
|
|
24727
25177
|
**Reference:** \`references/PLUGINS.md\`
|
|
@@ -24737,7 +25187,7 @@ Use this when:
|
|
|
24737
25187
|
- The user asks to query or update a connected turbopuffer namespace
|
|
24738
25188
|
- The user asks for PlanetScale organizations, databases, branches, or Insights data
|
|
24739
25189
|
- The user asks to analyze text with Pangram`;
|
|
24740
|
-
var
|
|
25190
|
+
var REFERENCE10 = `# Plugins
|
|
24741
25191
|
|
|
24742
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.
|
|
24743
25193
|
|
|
@@ -24908,12 +25358,12 @@ var PLUGINS_ABILITY = {
|
|
|
24908
25358
|
label: "Plugins",
|
|
24909
25359
|
description: "Use installed marketplace tools through @replicas/sdk.",
|
|
24910
25360
|
bullet: "- Interacting with installed marketplace plugins through TypeScript",
|
|
24911
|
-
section:
|
|
24912
|
-
referenceFile: { name: "PLUGINS.md", content:
|
|
25361
|
+
section: SECTION10,
|
|
25362
|
+
referenceFile: { name: "PLUGINS.md", content: REFERENCE10 }
|
|
24913
25363
|
};
|
|
24914
25364
|
|
|
24915
25365
|
// ../shared/src/default-skills/replicas-agent/abilities/replicas.ts
|
|
24916
|
-
var
|
|
25366
|
+
var SECTION11 = `### Replicas (in-workspace CLI)
|
|
24917
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.
|
|
24918
25368
|
|
|
24919
25369
|
**Reference:** \`references/REPLICAS.md\`
|
|
@@ -24924,7 +25374,7 @@ Use this when:
|
|
|
24924
25374
|
- The user asks "what envs / repos / automations do I have?"
|
|
24925
25375
|
- The user asks you to scaffold a \`replicas.json\` / \`replicas.yaml\` in a repo
|
|
24926
25376
|
- You need to run a long-lived service (dev server, daemon) \u2014 always use \`replicas service start\` so it survives workspace sleep/wake`;
|
|
24927
|
-
var
|
|
25377
|
+
var REFERENCE11 = `# Replicas (in-workspace CLI)
|
|
24928
25378
|
|
|
24929
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.
|
|
24930
25380
|
|
|
@@ -24962,6 +25412,7 @@ In agent mode the CLI hides commands that don't make sense for in-workspace agen
|
|
|
24962
25412
|
| \`replicas repos\` | List repos connected to the org |
|
|
24963
25413
|
| \`replicas environment ...\` | Manage environments, env vars, env files |
|
|
24964
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\`) |
|
|
24965
25416
|
| \`replicas preview ...\` | Register / list preview URLs (covered in \`PREVIEWS.md\`) |
|
|
24966
25417
|
| \`replicas service ...\` | Run long-lived services detached so they survive workspace sleep/wake (see below) |
|
|
24967
25418
|
| \`replicas media ...\` | Upload, list, share, revoke, or delete workspace media; follow \`MEDIA.md\` for destination embedding |
|
|
@@ -25155,13 +25606,13 @@ var REPLICAS_ABILITY = {
|
|
|
25155
25606
|
description: "Teach the agent about Replicas itself \u2014 automations, environments, the in-workspace CLI.",
|
|
25156
25607
|
// No bullet — help_instructions covers the `replicas` CLI surface in detail.
|
|
25157
25608
|
bullet: "",
|
|
25158
|
-
section:
|
|
25159
|
-
referenceFile: { name: "REPLICAS.md", content:
|
|
25609
|
+
section: SECTION11,
|
|
25610
|
+
referenceFile: { name: "REPLICAS.md", content: REFERENCE11 },
|
|
25160
25611
|
locked: true
|
|
25161
25612
|
};
|
|
25162
25613
|
|
|
25163
25614
|
// ../shared/src/default-skills/replicas-agent/abilities/sentry.ts
|
|
25164
|
-
var
|
|
25615
|
+
var SECTION12 = `### Sentry
|
|
25165
25616
|
Read issues and project data through the workspace-scoped TypeScript SDK.
|
|
25166
25617
|
|
|
25167
25618
|
**Reference:** \`references/SENTRY.md\`
|
|
@@ -25169,7 +25620,7 @@ Read issues and project data through the workspace-scoped TypeScript SDK.
|
|
|
25169
25620
|
Use this when:
|
|
25170
25621
|
- You need to inspect Sentry projects or issues
|
|
25171
25622
|
- A user asks for error-monitoring context outside a webhook-triggered task`;
|
|
25172
|
-
var
|
|
25623
|
+
var REFERENCE12 = `# Sentry Integration
|
|
25173
25624
|
|
|
25174
25625
|
Use \`@replicas/sdk\`; never request or read a Sentry token. Sentry access is organization-scoped and read-only.
|
|
25175
25626
|
|
|
@@ -25187,8 +25638,8 @@ var SENTRY_ABILITY = {
|
|
|
25187
25638
|
label: "Sentry",
|
|
25188
25639
|
description: "Read Sentry projects and issues through @replicas/sdk.",
|
|
25189
25640
|
bullet: "- Interacting with Sentry (reading projects, issues, and error context)",
|
|
25190
|
-
section:
|
|
25191
|
-
referenceFile: { name: "SENTRY.md", content:
|
|
25641
|
+
section: SECTION12,
|
|
25642
|
+
referenceFile: { name: "SENTRY.md", content: REFERENCE12 }
|
|
25192
25643
|
};
|
|
25193
25644
|
|
|
25194
25645
|
// ../shared/src/slack-response-style.ts
|
|
@@ -25198,7 +25649,7 @@ var SLACK_BLOCK_KIT_GUIDANCE = "Use Block Kit whenever structure or a link would
|
|
|
25198
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.';
|
|
25199
25650
|
|
|
25200
25651
|
// ../shared/src/default-skills/replicas-agent/abilities/slack.ts
|
|
25201
|
-
var
|
|
25652
|
+
var SECTION13 = `### Slack
|
|
25202
25653
|
Send messages, read threads, search conversations, and transfer files through the workspace-scoped TypeScript SDK.
|
|
25203
25654
|
|
|
25204
25655
|
**Reference:** \`references/SLACK.md\`
|
|
@@ -25208,7 +25659,7 @@ Use this when:
|
|
|
25208
25659
|
- You need to read or search Slack conversations
|
|
25209
25660
|
- You need to download a file attached to a Slack message
|
|
25210
25661
|
- You encounter a Slack message link and need its full thread`;
|
|
25211
|
-
var
|
|
25662
|
+
var REFERENCE13 = `# Slack Integration
|
|
25212
25663
|
|
|
25213
25664
|
Use \`@replicas/sdk\`; never read or send a Slack token directly. The SDK calls Replicas, which selects only this workspace's organization connection.
|
|
25214
25665
|
|
|
@@ -25286,8 +25737,8 @@ var SLACK_ABILITY = {
|
|
|
25286
25737
|
label: "Slack",
|
|
25287
25738
|
description: "Send messages, read threads, search, and transfer files through @replicas/sdk.",
|
|
25288
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.",
|
|
25289
|
-
section:
|
|
25290
|
-
referenceFile: { name: "SLACK.md", content:
|
|
25740
|
+
section: SECTION13,
|
|
25741
|
+
referenceFile: { name: "SLACK.md", content: REFERENCE13 }
|
|
25291
25742
|
};
|
|
25292
25743
|
|
|
25293
25744
|
// ../shared/src/default-skills/replicas-agent/registry.ts
|
|
@@ -25296,6 +25747,7 @@ var REPLICAS_AGENT_ABILITY_REGISTRY = {
|
|
|
25296
25747
|
memory: MEMORY_ABILITY,
|
|
25297
25748
|
computer: COMPUTER_ABILITY,
|
|
25298
25749
|
docker: DOCKER_ABILITY,
|
|
25750
|
+
environment_setup: ENVIRONMENT_SETUP_ABILITY,
|
|
25299
25751
|
github: GITHUB_ABILITY,
|
|
25300
25752
|
gitlab: GITLAB_ABILITY,
|
|
25301
25753
|
linear: LINEAR_ABILITY,
|
|
@@ -26262,7 +26714,7 @@ function parseOpencodeEvents(events) {
|
|
|
26262
26714
|
upsertDisplayMessage(messages, {
|
|
26263
26715
|
id,
|
|
26264
26716
|
type: "file_change",
|
|
26265
|
-
changes: files.map((
|
|
26717
|
+
changes: files.map((path7) => ({ path: path7, kind: "update" })),
|
|
26266
26718
|
status: "completed",
|
|
26267
26719
|
timestamp
|
|
26268
26720
|
});
|
|
@@ -27367,6 +27819,75 @@ var EGRESS_WORKSPACE_SHELL_VARS = {
|
|
|
27367
27819
|
EGRESS_EXIT_IP_ENDPOINTS: EGRESS_EXIT_IP_ENDPOINTS.join(" ")
|
|
27368
27820
|
};
|
|
27369
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
|
+
|
|
27370
27891
|
// ../shared/src/slash-commands.ts
|
|
27371
27892
|
var SIDE_CHAT_COMMANDS = ["/btw", "/side"];
|
|
27372
27893
|
var SLASH_COMMANDS = [
|
|
@@ -27418,9 +27939,6 @@ var HOOK_EXEC_MAX_BUFFER_BYTES = 10 * 1024 * 1024;
|
|
|
27418
27939
|
// ../shared/src/replicas-config.ts
|
|
27419
27940
|
var REPLICAS_CONFIG_FILENAMES = ["replicas.json", "replicas.yaml", "replicas.yml"];
|
|
27420
27941
|
|
|
27421
|
-
// ../shared/src/uuid.ts
|
|
27422
|
-
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
27423
|
-
|
|
27424
27942
|
// ../shared/src/terminal.ts
|
|
27425
27943
|
var CONTROL_CHARACTERS = /[\u0000-\u001F\u007F-\u009F]/g;
|
|
27426
27944
|
function sanitizeTerminalLine(value) {
|
|
@@ -27481,7 +27999,7 @@ var headlessFilesystemAgentResultSchema = external_exports.object({
|
|
|
27481
27999
|
});
|
|
27482
28000
|
|
|
27483
28001
|
// ../shared/src/cli-version.ts
|
|
27484
|
-
var CLI_VERSION = "0.2.
|
|
28002
|
+
var CLI_VERSION = "0.2.754";
|
|
27485
28003
|
|
|
27486
28004
|
// ../shared/src/version.ts
|
|
27487
28005
|
function compareVersions(v1, v2) {
|
|
@@ -28217,186 +28735,6 @@ function identityTokenUrl() {
|
|
|
28217
28735
|
return `http://127.0.0.1:${IDENTITY_PROXY_PORT}${IDENTITY_TOKEN_PATH}`;
|
|
28218
28736
|
}
|
|
28219
28737
|
|
|
28220
|
-
// ../shared/src/routes/environment-setups.ts
|
|
28221
|
-
var ENVIRONMENT_SETUP_STEPS = [
|
|
28222
|
-
{ key: "understand", label: "Understand the codebase" },
|
|
28223
|
-
{ key: "install", label: "Install dependencies and run the app" },
|
|
28224
|
-
{ key: "verify", label: "Verify checks and record a walkthrough" },
|
|
28225
|
-
{ key: "configure", label: "Draft hooks, system prompt, and automations" },
|
|
28226
|
-
{ key: "propose", label: "Propose the configuration for review" }
|
|
28227
|
-
];
|
|
28228
|
-
var ENVIRONMENT_SETUP_STEP_STATUSES = ["pending", "in_progress", "completed", "skipped"];
|
|
28229
|
-
var ENVIRONMENT_SETUP_RUN_STATUSES = ["running", "proposed", "applied", "failed", "cancelled"];
|
|
28230
|
-
var ENVIRONMENT_SETUP_AUTOMATION_ACTIONS = ["create", "update", "keep", "disable"];
|
|
28231
|
-
var ENVIRONMENT_SETUP_VERIFICATION_STATUSES = ["passed", "failed", "skipped"];
|
|
28232
|
-
var ENVIRONMENT_SETUP_LIMITS = {
|
|
28233
|
-
summaryChars: 600,
|
|
28234
|
-
stackItems: 30,
|
|
28235
|
-
nameChars: 120,
|
|
28236
|
-
descriptionChars: 1e3,
|
|
28237
|
-
systemPromptChars: 2e4,
|
|
28238
|
-
hookChars: 5e4,
|
|
28239
|
-
variables: 50,
|
|
28240
|
-
variableKeyChars: 128,
|
|
28241
|
-
variableDescriptionChars: 500,
|
|
28242
|
-
automations: 8,
|
|
28243
|
-
automationKeyChars: 80,
|
|
28244
|
-
automationPromptChars: 1e4,
|
|
28245
|
-
automationTriggers: 5,
|
|
28246
|
-
automationNoteChars: 300,
|
|
28247
|
-
verificationItems: 8,
|
|
28248
|
-
verificationDetailChars: 300,
|
|
28249
|
-
mediaItems: 8,
|
|
28250
|
-
repositories: 20
|
|
28251
|
-
};
|
|
28252
|
-
var ENVIRONMENT_SETUP_VARIABLE_WAIT = { defaultMs: 5 * 6e4, maxMs: 15 * 6e4, pollMs: 5e3 };
|
|
28253
|
-
var VARIABLE_KEY_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
28254
|
-
var text = (max) => max === void 0 ? external_exports.string().trim() : external_exports.string().trim().max(max);
|
|
28255
|
-
var requiredText = (max) => text(max).min(1, "must not be empty");
|
|
28256
|
-
var optionalText = (max) => text(max).nullish().transform((value) => value || null);
|
|
28257
|
-
var clearableText = (max) => text(max).nullish().transform((value) => value === void 0 ? void 0 : value || null);
|
|
28258
|
-
var list = (item, max) => max === void 0 ? external_exports.array(item) : external_exports.array(item).max(max);
|
|
28259
|
-
var ENVIRONMENT_SETUP_AUTHORED_TRIGGER_TYPES = ["cron", "github", "gitlab"];
|
|
28260
|
-
function isEnvironmentSetupAuthoredTriggerType(type) {
|
|
28261
|
-
return ENVIRONMENT_SETUP_AUTHORED_TRIGGER_TYPES.some((authored) => authored === type);
|
|
28262
|
-
}
|
|
28263
|
-
var repositoryTriggerConfigSchema = external_exports.object({
|
|
28264
|
-
event: external_exports.string(),
|
|
28265
|
-
repository_ids: external_exports.array(external_exports.string().regex(UUID_RE, "must be a repository id")).optional(),
|
|
28266
|
-
group_pr_events: external_exports.boolean().optional(),
|
|
28267
|
-
excluded_actors: external_exports.array(external_exports.string()).optional()
|
|
28268
|
-
});
|
|
28269
|
-
var proposalTriggerSchema = external_exports.discriminatedUnion("type", [
|
|
28270
|
-
external_exports.object({ type: external_exports.literal("cron"), config: external_exports.object({ schedule: external_exports.string(), timezone: external_exports.string().optional() }) }),
|
|
28271
|
-
external_exports.object({ type: external_exports.literal("github"), config: repositoryTriggerConfigSchema }),
|
|
28272
|
-
external_exports.object({ type: external_exports.literal("gitlab"), config: repositoryTriggerConfigSchema })
|
|
28273
|
-
]);
|
|
28274
|
-
var existingTriggerSchema = external_exports.custom(
|
|
28275
|
-
(value) => isRecord(value) && typeof value.type === "string" && isRecord(value.config),
|
|
28276
|
-
"must be an automation trigger"
|
|
28277
|
-
);
|
|
28278
|
-
var carriedTriggerSchema = existingTriggerSchema.refine(
|
|
28279
|
-
(trigger) => !isEnvironmentSetupAuthoredTriggerType(trigger.type)
|
|
28280
|
-
);
|
|
28281
|
-
function automationSchema(limits) {
|
|
28282
|
-
const authored = external_exports.object({
|
|
28283
|
-
name: text(limits.nameChars),
|
|
28284
|
-
description: text(limits.descriptionChars),
|
|
28285
|
-
prompt: text(limits.automationPromptChars),
|
|
28286
|
-
triggers: list(proposalTriggerSchema, limits.automationTriggers)
|
|
28287
|
-
});
|
|
28288
|
-
const updated = authored.extend({ triggers: list(external_exports.union([proposalTriggerSchema, carriedTriggerSchema]), limits.automationTriggers) });
|
|
28289
|
-
return external_exports.object({
|
|
28290
|
-
key: requiredText(limits.automationKeyChars),
|
|
28291
|
-
action: external_exports.enum(ENVIRONMENT_SETUP_AUTOMATION_ACTIONS).default("create"),
|
|
28292
|
-
automation_id: external_exports.string().regex(UUID_RE, "must be an automation id").nullable().default(null),
|
|
28293
|
-
name: text().default(""),
|
|
28294
|
-
description: optionalText().transform((value) => value ?? ""),
|
|
28295
|
-
prompt: text().default(""),
|
|
28296
|
-
triggers: list(existingTriggerSchema).default([]),
|
|
28297
|
-
note: optionalText(limits.automationNoteChars)
|
|
28298
|
-
}).superRefine((automation2, ctx) => {
|
|
28299
|
-
if (automation2.action === "create" && automation2.automation_id) {
|
|
28300
|
-
ctx.addIssue({ code: "custom", path: ["automation_id"], message: "belongs on an update, keep, or disable entry" });
|
|
28301
|
-
}
|
|
28302
|
-
if (automation2.action !== "create" && !automation2.automation_id) {
|
|
28303
|
-
ctx.addIssue({ code: "custom", path: ["automation_id"], message: "must be the id of an automation attached to this environment" });
|
|
28304
|
-
}
|
|
28305
|
-
if (automation2.action === "create" || automation2.action === "update") {
|
|
28306
|
-
if (!automation2.name) ctx.addIssue({ code: "custom", path: ["name"], message: "must not be empty" });
|
|
28307
|
-
if (!automation2.prompt) ctx.addIssue({ code: "custom", path: ["prompt"], message: "must not be empty" });
|
|
28308
|
-
if (automation2.triggers.length === 0) ctx.addIssue({ code: "custom", path: ["triggers"], message: "must not be empty" });
|
|
28309
|
-
}
|
|
28310
|
-
}).transform((automation2, ctx) => {
|
|
28311
|
-
if (automation2.action === "keep" || automation2.action === "disable") return automation2;
|
|
28312
|
-
const content = (automation2.action === "update" ? updated : authored).safeParse(automation2);
|
|
28313
|
-
if (content.success) return { ...automation2, ...content.data };
|
|
28314
|
-
for (const issue2 of content.error.issues) ctx.addIssue({ ...issue2, code: "custom" });
|
|
28315
|
-
return external_exports.NEVER;
|
|
28316
|
-
});
|
|
28317
|
-
}
|
|
28318
|
-
function automationListSchema(limits) {
|
|
28319
|
-
return list(automationSchema(limits)).default([]).superRefine((automations, ctx) => {
|
|
28320
|
-
if (new Set(automations.map((automation2) => automation2.key)).size !== automations.length) {
|
|
28321
|
-
ctx.addIssue({ code: "custom", message: "must have unique keys" });
|
|
28322
|
-
}
|
|
28323
|
-
const targets = automations.flatMap((automation2) => automation2.automation_id ?? []);
|
|
28324
|
-
if (new Set(targets).size !== targets.length) {
|
|
28325
|
-
ctx.addIssue({ code: "custom", message: "must mention each existing automation once" });
|
|
28326
|
-
}
|
|
28327
|
-
if (limits.automations !== void 0 && automations.filter((automation2) => automation2.action === "create").length > limits.automations) {
|
|
28328
|
-
ctx.addIssue({ code: "custom", message: `must create at most ${limits.automations} new automations` });
|
|
28329
|
-
}
|
|
28330
|
-
});
|
|
28331
|
-
}
|
|
28332
|
-
function environmentSchema(limits) {
|
|
28333
|
-
return external_exports.object({
|
|
28334
|
-
name: optionalText(limits.nameChars).transform((value) => value ?? void 0),
|
|
28335
|
-
description: clearableText(limits.descriptionChars),
|
|
28336
|
-
system_prompt: clearableText(limits.systemPromptChars),
|
|
28337
|
-
start_hook: clearableText(limits.hookChars),
|
|
28338
|
-
warm_hook: clearableText(limits.hookChars)
|
|
28339
|
-
});
|
|
28340
|
-
}
|
|
28341
|
-
function variableSchema(limits, requiredDefault) {
|
|
28342
|
-
return external_exports.object({
|
|
28343
|
-
key: external_exports.string().regex(VARIABLE_KEY_RE, "must be a valid environment variable name").max(limits.variableKeyChars ?? Number.POSITIVE_INFINITY),
|
|
28344
|
-
description: optionalText(limits.variableDescriptionChars).transform((value) => value ?? ""),
|
|
28345
|
-
required: external_exports.boolean().default(requiredDefault)
|
|
28346
|
-
});
|
|
28347
|
-
}
|
|
28348
|
-
function proposalSchema(limits) {
|
|
28349
|
-
return external_exports.object({
|
|
28350
|
-
summary: requiredText(limits.summaryChars),
|
|
28351
|
-
stack: list(text(), limits.stackItems).default([]).transform((items) => items.filter(Boolean)),
|
|
28352
|
-
environment: environmentSchema(limits),
|
|
28353
|
-
variables: list(variableSchema(limits, false), limits.variables).default([]),
|
|
28354
|
-
automations: automationListSchema(limits),
|
|
28355
|
-
verification: list(external_exports.object({
|
|
28356
|
-
label: requiredText(limits.nameChars),
|
|
28357
|
-
status: external_exports.enum(ENVIRONMENT_SETUP_VERIFICATION_STATUSES),
|
|
28358
|
-
detail: optionalText(limits.verificationDetailChars).transform((value) => value ?? void 0)
|
|
28359
|
-
}), limits.verificationItems).default([]),
|
|
28360
|
-
media: list(external_exports.object({
|
|
28361
|
-
media_id: external_exports.string().regex(UUID_RE, "must be a media id"),
|
|
28362
|
-
title: requiredText(limits.nameChars)
|
|
28363
|
-
}), limits.mediaItems).default([])
|
|
28364
|
-
});
|
|
28365
|
-
}
|
|
28366
|
-
var environmentSetupProposalSchema = proposalSchema({});
|
|
28367
|
-
var environmentSetupProposalSubmissionSchema = proposalSchema(ENVIRONMENT_SETUP_LIMITS);
|
|
28368
|
-
var environmentSetupVariableRequestSchema = variableSchema({}, false).extend({
|
|
28369
|
-
status: external_exports.enum(["pending", "provided", "skipped"]),
|
|
28370
|
-
requested_at: external_exports.string(),
|
|
28371
|
-
resolved_at: external_exports.string().nullable().default(null)
|
|
28372
|
-
});
|
|
28373
|
-
var environmentSetupRunStateSchema = external_exports.object({
|
|
28374
|
-
status: external_exports.enum(ENVIRONMENT_SETUP_RUN_STATUSES),
|
|
28375
|
-
steps: external_exports.partialRecord(external_exports.enum(ENVIRONMENT_SETUP_STEPS.map((step) => step.key)), external_exports.enum(ENVIRONMENT_SETUP_STEP_STATUSES)).default({}),
|
|
28376
|
-
proposal: environmentSetupProposalSchema.nullable().default(null),
|
|
28377
|
-
applied: external_exports.object({
|
|
28378
|
-
applied_at: external_exports.string(),
|
|
28379
|
-
automation_ids: external_exports.array(external_exports.string())
|
|
28380
|
-
}).nullable().default(null),
|
|
28381
|
-
variable_requests: external_exports.array(environmentSetupVariableRequestSchema).default([])
|
|
28382
|
-
});
|
|
28383
|
-
var applyEnvironmentSetupRequestSchema = external_exports.object({
|
|
28384
|
-
environment: environmentSchema(ENVIRONMENT_SETUP_LIMITS).extend({ name: requiredText(ENVIRONMENT_SETUP_LIMITS.nameChars) }),
|
|
28385
|
-
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)),
|
|
28386
|
-
automations: automationListSchema(ENVIRONMENT_SETUP_LIMITS)
|
|
28387
|
-
});
|
|
28388
|
-
var requestEnvironmentSetupVariablesSchema = external_exports.object({
|
|
28389
|
-
variables: list(variableSchema(ENVIRONMENT_SETUP_LIMITS, true), ENVIRONMENT_SETUP_LIMITS.variables).min(1, "must not be empty")
|
|
28390
|
-
}).superRefine(({ variables }, ctx) => {
|
|
28391
|
-
if (new Set(variables.map((variable) => variable.key)).size !== variables.length) {
|
|
28392
|
-
ctx.addIssue({ code: "custom", path: ["variables"], message: "must have unique keys" });
|
|
28393
|
-
}
|
|
28394
|
-
});
|
|
28395
|
-
var respondEnvironmentSetupVariablesSchema = external_exports.object({
|
|
28396
|
-
values: external_exports.record(external_exports.string().regex(VARIABLE_KEY_RE), external_exports.string()).default({}),
|
|
28397
|
-
skipped: external_exports.array(external_exports.string().regex(VARIABLE_KEY_RE)).default([])
|
|
28398
|
-
});
|
|
28399
|
-
|
|
28400
28738
|
// src/lib/monolith-url.ts
|
|
28401
28739
|
var MONOLITH_URL = process.env.REPLICAS_MONOLITH_URL || process.env.MONOLITH_URL || "https://api.replicas.dev";
|
|
28402
28740
|
|
|
@@ -29976,8 +30314,8 @@ async function claudeAuthCommand(options = {}) {
|
|
|
29976
30314
|
var CLIENT_ID = "1031625952748946";
|
|
29977
30315
|
var AUTH_URL = "https://auth.meta.com";
|
|
29978
30316
|
var API_KEY_URL = "https://api.meta.ai/muse-code/key";
|
|
29979
|
-
async function post(
|
|
29980
|
-
return fetch(`${AUTH_URL}${
|
|
30317
|
+
async function post(path7, body) {
|
|
30318
|
+
return fetch(`${AUTH_URL}${path7}`, {
|
|
29981
30319
|
method: "POST",
|
|
29982
30320
|
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
29983
30321
|
body
|
|
@@ -30652,14 +30990,163 @@ Repositories (${response.repositories.length}):
|
|
|
30652
30990
|
}
|
|
30653
30991
|
}
|
|
30654
30992
|
|
|
30655
|
-
// 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"));
|
|
30656
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"));
|
|
30657
31144
|
var import_prompts7 = __toESM(require("prompts"));
|
|
30658
31145
|
function parseScopeFilter(value) {
|
|
30659
31146
|
if (!value) return void 0;
|
|
30660
31147
|
if (value === "org" || value === "user" || value === "all") return value;
|
|
30661
|
-
console.log(
|
|
30662
|
-
console.log(
|
|
31148
|
+
console.log(import_chalk20.default.red(`Invalid --owner: ${value}`));
|
|
31149
|
+
console.log(import_chalk20.default.gray("Valid options: org, user, all"));
|
|
30663
31150
|
process.exit(1);
|
|
30664
31151
|
}
|
|
30665
31152
|
function parseAgentProviderOption(value) {
|
|
@@ -30668,8 +31155,8 @@ function parseAgentProviderOption(value) {
|
|
|
30668
31155
|
if (trimmed === "" || trimmed.toLowerCase() === "none") return null;
|
|
30669
31156
|
const lower = trimmed.toLowerCase();
|
|
30670
31157
|
if (!isValidAgentProvider(lower)) {
|
|
30671
|
-
console.log(
|
|
30672
|
-
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`));
|
|
30673
31160
|
process.exit(1);
|
|
30674
31161
|
}
|
|
30675
31162
|
return lower;
|
|
@@ -30680,8 +31167,8 @@ function parseThinkingLevelOption(value) {
|
|
|
30680
31167
|
if (trimmed === "" || trimmed.toLowerCase() === "none") return null;
|
|
30681
31168
|
const lower = trimmed.toLowerCase();
|
|
30682
31169
|
if (!isValidThinkingLevel(lower)) {
|
|
30683
|
-
console.log(
|
|
30684
|
-
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`));
|
|
30685
31172
|
process.exit(1);
|
|
30686
31173
|
}
|
|
30687
31174
|
return lower;
|
|
@@ -30698,8 +31185,8 @@ function isAutomationLifecyclePolicy(value) {
|
|
|
30698
31185
|
function parseWorkspaceLifecyclePolicyOption(value) {
|
|
30699
31186
|
if (!value) return void 0;
|
|
30700
31187
|
if (isAutomationLifecyclePolicy(value)) return value;
|
|
30701
|
-
console.log(
|
|
30702
|
-
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(", ")}`));
|
|
30703
31190
|
process.exit(1);
|
|
30704
31191
|
}
|
|
30705
31192
|
function parseExcludedActorsOption(value) {
|
|
@@ -30718,7 +31205,7 @@ function withExcludedActors(config3, excludedActors) {
|
|
|
30718
31205
|
}
|
|
30719
31206
|
function parseAutomationLifecycleOptions(options) {
|
|
30720
31207
|
if (options.sleepWhenDone && options.lifecycle && options.lifecycle !== "sleep_when_done") {
|
|
30721
|
-
console.log(
|
|
31208
|
+
console.log(import_chalk20.default.red("--sleep-when-done cannot be combined with a different --lifecycle value"));
|
|
30722
31209
|
process.exit(1);
|
|
30723
31210
|
}
|
|
30724
31211
|
if (options.sleepWhenDone) return "sleep_when_done";
|
|
@@ -30727,7 +31214,7 @@ function parseAutomationLifecycleOptions(options) {
|
|
|
30727
31214
|
function applyAgentSelection(body, existing) {
|
|
30728
31215
|
const result = validateAgentSelection(body, existing, AGENT_MODELS);
|
|
30729
31216
|
if (!result.ok) {
|
|
30730
|
-
console.log(
|
|
31217
|
+
console.log(import_chalk20.default.red(result.error.message));
|
|
30731
31218
|
process.exit(1);
|
|
30732
31219
|
}
|
|
30733
31220
|
const out = {};
|
|
@@ -30768,8 +31255,8 @@ function resolveTriggerRepositoryIds(repositories, repoNamesInput, provider) {
|
|
|
30768
31255
|
for (const repoName of repoNames) {
|
|
30769
31256
|
const repo = providerRepos.find((r) => r.name === repoName);
|
|
30770
31257
|
if (!repo) {
|
|
30771
|
-
console.log(
|
|
30772
|
-
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(", ")}`));
|
|
30773
31260
|
process.exit(1);
|
|
30774
31261
|
}
|
|
30775
31262
|
repoIds.push(repo.id);
|
|
@@ -30802,43 +31289,43 @@ function formatModeSummary(automation2) {
|
|
|
30802
31289
|
function resolveSelectableEnvironmentId(envInput, selectableEnvs) {
|
|
30803
31290
|
const resolved = resolveByNameOrId(envInput, selectableEnvs);
|
|
30804
31291
|
if (!resolved) {
|
|
30805
|
-
console.log(
|
|
31292
|
+
console.log(import_chalk20.default.red(`Environment not found: ${envInput}`));
|
|
30806
31293
|
const available = selectableEnvs.map((e) => e.name).join(", ");
|
|
30807
|
-
console.log(
|
|
31294
|
+
console.log(import_chalk20.default.gray(`Available: ${available || "(none)"}`));
|
|
30808
31295
|
process.exit(1);
|
|
30809
31296
|
}
|
|
30810
31297
|
return resolved.id;
|
|
30811
31298
|
}
|
|
30812
31299
|
function printAutomation(automation2) {
|
|
30813
|
-
console.log(
|
|
30814
|
-
console.log(
|
|
30815
|
-
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"}`));
|
|
30816
31303
|
if (automation2.description) {
|
|
30817
|
-
console.log(
|
|
31304
|
+
console.log(import_chalk20.default.gray(` Description: ${automation2.description}`));
|
|
30818
31305
|
}
|
|
30819
|
-
console.log(
|
|
31306
|
+
console.log(import_chalk20.default.gray(` Enabled: ${automation2.enabled ? import_chalk20.default.green("yes") : import_chalk20.default.red("no")}`));
|
|
30820
31307
|
if (automation2.triggers.length > 0) {
|
|
30821
|
-
console.log(
|
|
31308
|
+
console.log(import_chalk20.default.gray(` Triggers: ${automation2.triggers.map(formatTrigger).join(", ")}`));
|
|
30822
31309
|
}
|
|
30823
31310
|
if (automation2.github_check_names.length > 0) {
|
|
30824
|
-
console.log(
|
|
31311
|
+
console.log(import_chalk20.default.gray(` GitHub checks: ${automation2.github_check_names.join(", ")}`));
|
|
30825
31312
|
}
|
|
30826
|
-
console.log(
|
|
31313
|
+
console.log(import_chalk20.default.gray(` Prompt: ${truncate2(automation2.prompt, 80)}`));
|
|
30827
31314
|
if (automation2.cron_next_fire_at) {
|
|
30828
|
-
console.log(
|
|
31315
|
+
console.log(import_chalk20.default.gray(` Next Run: ${formatDate2(automation2.cron_next_fire_at)}`));
|
|
30829
31316
|
}
|
|
30830
31317
|
if (automation2.workspace_lifecycle_policy && automation2.workspace_lifecycle_policy !== "default") {
|
|
30831
|
-
console.log(
|
|
31318
|
+
console.log(import_chalk20.default.gray(` Lifecycle: ${automation2.workspace_lifecycle_policy}`));
|
|
30832
31319
|
}
|
|
30833
31320
|
if (automation2.agent_provider || automation2.model || automation2.thinking_level) {
|
|
30834
|
-
console.log(
|
|
31321
|
+
console.log(import_chalk20.default.gray(` Agent: ${formatAgentSummary(automation2)}`));
|
|
30835
31322
|
}
|
|
30836
31323
|
if (automation2.plan_mode || automation2.goal_mode || automation2.fast_mode) {
|
|
30837
|
-
console.log(
|
|
31324
|
+
console.log(import_chalk20.default.gray(` Modes: ${formatModeSummary(automation2)}`));
|
|
30838
31325
|
}
|
|
30839
|
-
console.log(
|
|
30840
|
-
console.log(
|
|
30841
|
-
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)}`));
|
|
30842
31329
|
console.log();
|
|
30843
31330
|
}
|
|
30844
31331
|
async function automationListCommand(options) {
|
|
@@ -30857,17 +31344,17 @@ async function automationListCommand(options) {
|
|
|
30857
31344
|
`/v1/automations${query ? "?" + query : ""}`
|
|
30858
31345
|
);
|
|
30859
31346
|
if (response.automations.length === 0) {
|
|
30860
|
-
console.log(
|
|
31347
|
+
console.log(import_chalk20.default.yellow("\nNo automations found.\n"));
|
|
30861
31348
|
return;
|
|
30862
31349
|
}
|
|
30863
|
-
console.log(
|
|
31350
|
+
console.log(import_chalk20.default.green(`
|
|
30864
31351
|
Automations (Page ${response.page} of ${response.totalPages}, Total: ${response.total}):
|
|
30865
31352
|
`));
|
|
30866
31353
|
for (const automation2 of response.automations) {
|
|
30867
31354
|
printAutomation(automation2);
|
|
30868
31355
|
}
|
|
30869
31356
|
} catch (error51) {
|
|
30870
|
-
console.error(
|
|
31357
|
+
console.error(import_chalk20.default.red(`Error: ${error51 instanceof Error ? error51.message : "Unknown error"}`));
|
|
30871
31358
|
process.exit(1);
|
|
30872
31359
|
}
|
|
30873
31360
|
}
|
|
@@ -30876,50 +31363,50 @@ async function automationGetCommand(id) {
|
|
|
30876
31363
|
try {
|
|
30877
31364
|
const response = await orgAuthenticatedFetch(`/v1/automations/${id}`);
|
|
30878
31365
|
const automation2 = response.automation;
|
|
30879
|
-
console.log(
|
|
31366
|
+
console.log(import_chalk20.default.green(`
|
|
30880
31367
|
Automation: ${automation2.name}
|
|
30881
31368
|
`));
|
|
30882
|
-
console.log(
|
|
31369
|
+
console.log(import_chalk20.default.gray(` ID: ${automation2.id}`));
|
|
30883
31370
|
if (automation2.description) {
|
|
30884
|
-
console.log(
|
|
31371
|
+
console.log(import_chalk20.default.gray(` Description: ${automation2.description}`));
|
|
30885
31372
|
}
|
|
30886
|
-
console.log(
|
|
31373
|
+
console.log(import_chalk20.default.gray(` Enabled: ${automation2.enabled ? import_chalk20.default.green("yes") : import_chalk20.default.red("no")}`));
|
|
30887
31374
|
if (automation2.triggers.length > 0) {
|
|
30888
|
-
console.log(
|
|
31375
|
+
console.log(import_chalk20.default.gray(` Triggers:`));
|
|
30889
31376
|
for (const trigger of automation2.triggers) {
|
|
30890
|
-
console.log(
|
|
31377
|
+
console.log(import_chalk20.default.gray(` - ${formatTrigger(trigger)}`));
|
|
30891
31378
|
}
|
|
30892
31379
|
}
|
|
30893
31380
|
if (automation2.github_check_names.length > 0) {
|
|
30894
|
-
console.log(
|
|
31381
|
+
console.log(import_chalk20.default.gray(` GitHub checks: ${automation2.github_check_names.join(", ")}`));
|
|
30895
31382
|
}
|
|
30896
|
-
console.log(
|
|
30897
|
-
console.log(
|
|
31383
|
+
console.log(import_chalk20.default.gray(` Prompt: ${automation2.prompt}`));
|
|
31384
|
+
console.log(import_chalk20.default.gray(` Environment: ${automation2.environment_id}`));
|
|
30898
31385
|
if (automation2.cron_expression) {
|
|
30899
|
-
console.log(
|
|
31386
|
+
console.log(import_chalk20.default.gray(` Cron: ${automation2.cron_expression}`));
|
|
30900
31387
|
}
|
|
30901
31388
|
if (automation2.cron_timezone) {
|
|
30902
|
-
console.log(
|
|
31389
|
+
console.log(import_chalk20.default.gray(` Timezone: ${automation2.cron_timezone}`));
|
|
30903
31390
|
}
|
|
30904
31391
|
if (automation2.cron_next_fire_at) {
|
|
30905
|
-
console.log(
|
|
31392
|
+
console.log(import_chalk20.default.gray(` Next Run: ${formatDate2(automation2.cron_next_fire_at)}`));
|
|
30906
31393
|
}
|
|
30907
31394
|
if (automation2.workspace_lifecycle_policy) {
|
|
30908
|
-
console.log(
|
|
31395
|
+
console.log(import_chalk20.default.gray(` Lifecycle Policy: ${automation2.workspace_lifecycle_policy}`));
|
|
30909
31396
|
}
|
|
30910
31397
|
if (automation2.workspace_auto_stop_minutes) {
|
|
30911
|
-
console.log(
|
|
30912
|
-
}
|
|
30913
|
-
console.log(
|
|
30914
|
-
console.log(
|
|
30915
|
-
console.log(
|
|
30916
|
-
console.log(
|
|
30917
|
-
console.log(
|
|
30918
|
-
console.log(
|
|
30919
|
-
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)}`));
|
|
30920
31407
|
console.log();
|
|
30921
31408
|
} catch (error51) {
|
|
30922
|
-
console.error(
|
|
31409
|
+
console.error(import_chalk20.default.red(`Error: ${error51 instanceof Error ? error51.message : "Unknown error"}`));
|
|
30923
31410
|
process.exit(1);
|
|
30924
31411
|
}
|
|
30925
31412
|
}
|
|
@@ -31044,22 +31531,22 @@ async function automationCreateCommand(name, options) {
|
|
|
31044
31531
|
ensureOrgApiAuthenticated();
|
|
31045
31532
|
const lifecyclePolicy = parseAutomationLifecycleOptions(options);
|
|
31046
31533
|
if (options.autoStopMinutes && !lifecyclePolicySupportsAutoStop(lifecyclePolicy ?? "default")) {
|
|
31047
|
-
console.log(
|
|
31534
|
+
console.log(import_chalk20.default.red("--auto-stop-minutes requires --lifecycle default"));
|
|
31048
31535
|
process.exit(1);
|
|
31049
31536
|
}
|
|
31050
31537
|
if (options.autoStopMinutes) {
|
|
31051
31538
|
const minutes = parseInt(options.autoStopMinutes, 10);
|
|
31052
31539
|
if (isNaN(minutes) || minutes < 3 || minutes > 1440) {
|
|
31053
|
-
console.log(
|
|
31540
|
+
console.log(import_chalk20.default.red("--auto-stop-minutes must be between 3 and 1440"));
|
|
31054
31541
|
process.exit(1);
|
|
31055
31542
|
}
|
|
31056
31543
|
}
|
|
31057
31544
|
if (options.triggerGithubExcludeUsers !== void 0 && !options.triggerGithub) {
|
|
31058
|
-
console.log(
|
|
31545
|
+
console.log(import_chalk20.default.red("--trigger-github-exclude-users requires --trigger-github"));
|
|
31059
31546
|
process.exit(1);
|
|
31060
31547
|
}
|
|
31061
31548
|
if (options.triggerGitlabExcludeUsers !== void 0 && !options.triggerGitlab) {
|
|
31062
|
-
console.log(
|
|
31549
|
+
console.log(import_chalk20.default.red("--trigger-gitlab-exclude-users requires --trigger-gitlab"));
|
|
31063
31550
|
process.exit(1);
|
|
31064
31551
|
}
|
|
31065
31552
|
const hasConfirmation = options.confirmationChannel || options.confirmationThread || options.confirmationMessageTs || options.confirmationUser;
|
|
@@ -31086,7 +31573,7 @@ async function automationCreateCommand(name, options) {
|
|
|
31086
31573
|
);
|
|
31087
31574
|
const selectableEnvs = envResponse.environments;
|
|
31088
31575
|
if (selectableEnvs.length === 0) {
|
|
31089
|
-
console.log(
|
|
31576
|
+
console.log(import_chalk20.default.red("No environments found. Please create an environment first."));
|
|
31090
31577
|
process.exit(1);
|
|
31091
31578
|
}
|
|
31092
31579
|
const repoResponse = await orgAuthenticatedFetch("/v1/repositories");
|
|
@@ -31100,7 +31587,7 @@ async function automationCreateCommand(name, options) {
|
|
|
31100
31587
|
validate: (value) => value.trim() ? true : "Name is required"
|
|
31101
31588
|
});
|
|
31102
31589
|
if (!response2.name) {
|
|
31103
|
-
console.log(
|
|
31590
|
+
console.log(import_chalk20.default.yellow("\nCancelled."));
|
|
31104
31591
|
return;
|
|
31105
31592
|
}
|
|
31106
31593
|
automationName = response2.name;
|
|
@@ -31114,7 +31601,7 @@ async function automationCreateCommand(name, options) {
|
|
|
31114
31601
|
validate: (value) => value.trim() ? true : "Prompt is required"
|
|
31115
31602
|
});
|
|
31116
31603
|
if (!response2.prompt) {
|
|
31117
|
-
console.log(
|
|
31604
|
+
console.log(import_chalk20.default.yellow("\nCancelled."));
|
|
31118
31605
|
return;
|
|
31119
31606
|
}
|
|
31120
31607
|
automationPrompt = response2.prompt;
|
|
@@ -31134,7 +31621,7 @@ async function automationCreateCommand(name, options) {
|
|
|
31134
31621
|
}))
|
|
31135
31622
|
});
|
|
31136
31623
|
if (!envResponse2.env) {
|
|
31137
|
-
console.log(
|
|
31624
|
+
console.log(import_chalk20.default.yellow("\nCancelled."));
|
|
31138
31625
|
return;
|
|
31139
31626
|
}
|
|
31140
31627
|
selectedEnvironmentId = envResponse2.env;
|
|
@@ -31176,7 +31663,7 @@ async function automationCreateCommand(name, options) {
|
|
|
31176
31663
|
if (triggers.length === 0) {
|
|
31177
31664
|
triggers = await promptForTriggers(repositories.map((r) => ({ id: r.id, name: r.name, provider: r.provider })));
|
|
31178
31665
|
if (triggers.length === 0) {
|
|
31179
|
-
console.log(
|
|
31666
|
+
console.log(import_chalk20.default.red("At least one trigger is required."));
|
|
31180
31667
|
process.exit(1);
|
|
31181
31668
|
}
|
|
31182
31669
|
}
|
|
@@ -31207,25 +31694,25 @@ async function automationCreateCommand(name, options) {
|
|
|
31207
31694
|
...agentSelection,
|
|
31208
31695
|
...mothershipConfirmation ? { mothership_confirmation: mothershipConfirmation } : {}
|
|
31209
31696
|
};
|
|
31210
|
-
console.log(
|
|
31697
|
+
console.log(import_chalk20.default.gray("\nCreating automation..."));
|
|
31211
31698
|
const response = await orgAuthenticatedFetch("/v1/automations", {
|
|
31212
31699
|
method: "POST",
|
|
31213
31700
|
body
|
|
31214
31701
|
});
|
|
31215
31702
|
const automation2 = response.automation;
|
|
31216
|
-
console.log(
|
|
31703
|
+
console.log(import_chalk20.default.green(`
|
|
31217
31704
|
Created automation: ${automation2.name}`));
|
|
31218
|
-
console.log(
|
|
31219
|
-
console.log(
|
|
31705
|
+
console.log(import_chalk20.default.gray(` ID: ${automation2.id}`));
|
|
31706
|
+
console.log(import_chalk20.default.gray(` Enabled: ${automation2.enabled ? "yes" : "no"}`));
|
|
31220
31707
|
if (automation2.triggers.length > 0) {
|
|
31221
|
-
console.log(
|
|
31708
|
+
console.log(import_chalk20.default.gray(` Triggers: ${automation2.triggers.map(formatTrigger).join(", ")}`));
|
|
31222
31709
|
}
|
|
31223
31710
|
if (automation2.cron_next_fire_at) {
|
|
31224
|
-
console.log(
|
|
31711
|
+
console.log(import_chalk20.default.gray(` Next Run: ${formatDate2(automation2.cron_next_fire_at)}`));
|
|
31225
31712
|
}
|
|
31226
31713
|
console.log();
|
|
31227
31714
|
} catch (error51) {
|
|
31228
|
-
console.error(
|
|
31715
|
+
console.error(import_chalk20.default.red(`Error: ${error51 instanceof Error ? error51.message : "Unknown error"}`));
|
|
31229
31716
|
process.exit(1);
|
|
31230
31717
|
}
|
|
31231
31718
|
}
|
|
@@ -31235,17 +31722,17 @@ async function automationEditCommand(id, options) {
|
|
|
31235
31722
|
if (options.autoStopMinutes) {
|
|
31236
31723
|
const minutes = parseInt(options.autoStopMinutes, 10);
|
|
31237
31724
|
if (isNaN(minutes) || minutes < 3 || minutes > 1440) {
|
|
31238
|
-
console.log(
|
|
31725
|
+
console.log(import_chalk20.default.red("--auto-stop-minutes must be between 3 and 1440"));
|
|
31239
31726
|
process.exit(1);
|
|
31240
31727
|
}
|
|
31241
31728
|
}
|
|
31242
31729
|
const replacingTriggers = Boolean(options.triggerCron || options.triggerGithub || options.triggerGitlab);
|
|
31243
31730
|
if (replacingTriggers && options.triggerGithubExcludeUsers !== void 0 && !options.triggerGithub) {
|
|
31244
|
-
console.log(
|
|
31731
|
+
console.log(import_chalk20.default.red("--trigger-github-exclude-users requires --trigger-github when replacing triggers"));
|
|
31245
31732
|
process.exit(1);
|
|
31246
31733
|
}
|
|
31247
31734
|
if (replacingTriggers && options.triggerGitlabExcludeUsers !== void 0 && !options.triggerGitlab) {
|
|
31248
|
-
console.log(
|
|
31735
|
+
console.log(import_chalk20.default.red("--trigger-gitlab-exclude-users requires --trigger-gitlab when replacing triggers"));
|
|
31249
31736
|
process.exit(1);
|
|
31250
31737
|
}
|
|
31251
31738
|
const parsedAgent = {
|
|
@@ -31257,7 +31744,7 @@ async function automationEditCommand(id, options) {
|
|
|
31257
31744
|
const existing = await orgAuthenticatedFetch(`/v1/automations/${id}`);
|
|
31258
31745
|
const autoStopLifecyclePolicy = lifecyclePolicy ?? toAutomationLifecyclePolicy(existing.automation.workspace_lifecycle_policy);
|
|
31259
31746
|
if (options.autoStopMinutes && !lifecyclePolicySupportsAutoStop(autoStopLifecyclePolicy)) {
|
|
31260
|
-
console.log(
|
|
31747
|
+
console.log(import_chalk20.default.red("--auto-stop-minutes requires --lifecycle default"));
|
|
31261
31748
|
process.exit(1);
|
|
31262
31749
|
}
|
|
31263
31750
|
const agentSelection = applyAgentSelection(parsedAgent, {
|
|
@@ -31397,11 +31884,11 @@ async function automationEditCommand(id, options) {
|
|
|
31397
31884
|
return trigger;
|
|
31398
31885
|
});
|
|
31399
31886
|
if (!matchedGithub) {
|
|
31400
|
-
console.log(
|
|
31887
|
+
console.log(import_chalk20.default.red("No existing GitHub trigger found. Pass --trigger-github to create one."));
|
|
31401
31888
|
process.exit(1);
|
|
31402
31889
|
}
|
|
31403
31890
|
if (!matchedGitlab) {
|
|
31404
|
-
console.log(
|
|
31891
|
+
console.log(import_chalk20.default.red("No existing GitLab trigger found. Pass --trigger-gitlab to create one."));
|
|
31405
31892
|
process.exit(1);
|
|
31406
31893
|
}
|
|
31407
31894
|
}
|
|
@@ -31426,25 +31913,25 @@ async function automationEditCommand(id, options) {
|
|
|
31426
31913
|
Object.assign(body, agentSelection);
|
|
31427
31914
|
}
|
|
31428
31915
|
if (Object.keys(body).length === 0) {
|
|
31429
|
-
console.log(
|
|
31916
|
+
console.log(import_chalk20.default.yellow("\nNo changes made.\n"));
|
|
31430
31917
|
return;
|
|
31431
31918
|
}
|
|
31432
|
-
console.log(
|
|
31919
|
+
console.log(import_chalk20.default.gray("\nUpdating automation..."));
|
|
31433
31920
|
const response = await orgAuthenticatedFetch(`/v1/automations/${id}`, {
|
|
31434
31921
|
method: "PATCH",
|
|
31435
31922
|
body
|
|
31436
31923
|
});
|
|
31437
31924
|
const automation2 = response.automation;
|
|
31438
|
-
console.log(
|
|
31925
|
+
console.log(import_chalk20.default.green(`
|
|
31439
31926
|
Updated automation: ${automation2.name}`));
|
|
31440
|
-
console.log(
|
|
31441
|
-
console.log(
|
|
31927
|
+
console.log(import_chalk20.default.gray(` ID: ${automation2.id}`));
|
|
31928
|
+
console.log(import_chalk20.default.gray(` Enabled: ${automation2.enabled ? "yes" : "no"}`));
|
|
31442
31929
|
if (automation2.triggers.length > 0) {
|
|
31443
|
-
console.log(
|
|
31930
|
+
console.log(import_chalk20.default.gray(` Triggers: ${automation2.triggers.map(formatTrigger).join(", ")}`));
|
|
31444
31931
|
}
|
|
31445
31932
|
console.log();
|
|
31446
31933
|
} catch (error51) {
|
|
31447
|
-
console.error(
|
|
31934
|
+
console.error(import_chalk20.default.red(`Error: ${error51 instanceof Error ? error51.message : "Unknown error"}`));
|
|
31448
31935
|
process.exit(1);
|
|
31449
31936
|
}
|
|
31450
31937
|
}
|
|
@@ -31455,12 +31942,12 @@ async function automationRunCommand(id) {
|
|
|
31455
31942
|
const automation2 = existing.automation;
|
|
31456
31943
|
const hasCronTrigger = automation2.triggers.some((t) => t.type === "cron");
|
|
31457
31944
|
if (!hasCronTrigger) {
|
|
31458
|
-
console.log(
|
|
31459
|
-
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(", ")}`));
|
|
31460
31947
|
console.log();
|
|
31461
31948
|
process.exit(1);
|
|
31462
31949
|
}
|
|
31463
|
-
console.log(
|
|
31950
|
+
console.log(import_chalk20.default.gray(`
|
|
31464
31951
|
Triggering automation "${automation2.name}"...`));
|
|
31465
31952
|
const response = await orgAuthenticatedFetch(
|
|
31466
31953
|
`/v1/automations/${id}/trigger`,
|
|
@@ -31470,20 +31957,20 @@ Triggering automation "${automation2.name}"...`));
|
|
|
31470
31957
|
}
|
|
31471
31958
|
);
|
|
31472
31959
|
if (!response.execution_id) {
|
|
31473
|
-
console.log(
|
|
31960
|
+
console.log(import_chalk20.default.red(`
|
|
31474
31961
|
Automation trigger returned no execution ID. The automation may not have started.`));
|
|
31475
31962
|
console.log();
|
|
31476
31963
|
process.exit(1);
|
|
31477
31964
|
}
|
|
31478
|
-
console.log(
|
|
31965
|
+
console.log(import_chalk20.default.green(`
|
|
31479
31966
|
Automation triggered successfully.`));
|
|
31480
|
-
console.log(
|
|
31967
|
+
console.log(import_chalk20.default.gray(` Execution ID: ${response.execution_id}`));
|
|
31481
31968
|
if (response.workspace_id) {
|
|
31482
|
-
console.log(
|
|
31969
|
+
console.log(import_chalk20.default.gray(` Workspace ID: ${response.workspace_id}`));
|
|
31483
31970
|
}
|
|
31484
31971
|
console.log();
|
|
31485
31972
|
} catch (error51) {
|
|
31486
|
-
console.error(
|
|
31973
|
+
console.error(import_chalk20.default.red(`Error: ${error51 instanceof Error ? error51.message : "Unknown error"}`));
|
|
31487
31974
|
process.exit(1);
|
|
31488
31975
|
}
|
|
31489
31976
|
}
|
|
@@ -31500,38 +31987,38 @@ async function automationDeleteCommand(id, options) {
|
|
|
31500
31987
|
initial: false
|
|
31501
31988
|
});
|
|
31502
31989
|
if (!response.confirm) {
|
|
31503
|
-
console.log(
|
|
31990
|
+
console.log(import_chalk20.default.yellow("\nCancelled."));
|
|
31504
31991
|
return;
|
|
31505
31992
|
}
|
|
31506
31993
|
}
|
|
31507
31994
|
await orgAuthenticatedFetch(`/v1/automations/${id}`, {
|
|
31508
31995
|
method: "DELETE"
|
|
31509
31996
|
});
|
|
31510
|
-
console.log(
|
|
31997
|
+
console.log(import_chalk20.default.green(`
|
|
31511
31998
|
Automation "${automationName}" (${id}) deleted.
|
|
31512
31999
|
`));
|
|
31513
32000
|
} catch (error51) {
|
|
31514
|
-
console.error(
|
|
32001
|
+
console.error(import_chalk20.default.red(`Error: ${error51 instanceof Error ? error51.message : "Unknown error"}`));
|
|
31515
32002
|
process.exit(1);
|
|
31516
32003
|
}
|
|
31517
32004
|
}
|
|
31518
32005
|
async function automationCheckCommand(checkRunId, options) {
|
|
31519
32006
|
const id = Number(checkRunId);
|
|
31520
32007
|
if (!Number.isSafeInteger(id)) {
|
|
31521
|
-
console.error(
|
|
32008
|
+
console.error(import_chalk20.default.red("Error: check run ID must be an integer"));
|
|
31522
32009
|
process.exit(1);
|
|
31523
32010
|
}
|
|
31524
32011
|
if (!options.token) {
|
|
31525
|
-
console.error(
|
|
32012
|
+
console.error(import_chalk20.default.red("Error: --token is required"));
|
|
31526
32013
|
process.exit(1);
|
|
31527
32014
|
}
|
|
31528
32015
|
const { conclusion } = options;
|
|
31529
32016
|
if (!isAutomationCheckConclusion(conclusion)) {
|
|
31530
|
-
console.error(
|
|
32017
|
+
console.error(import_chalk20.default.red(`Error: --conclusion must be one of ${AUTOMATION_CHECK_CONCLUSIONS.join(", ")}`));
|
|
31531
32018
|
process.exit(1);
|
|
31532
32019
|
}
|
|
31533
32020
|
if (!options.title?.trim()) {
|
|
31534
|
-
console.error(
|
|
32021
|
+
console.error(import_chalk20.default.red("Error: --title is required"));
|
|
31535
32022
|
process.exit(1);
|
|
31536
32023
|
}
|
|
31537
32024
|
const body = {
|
|
@@ -31545,23 +32032,23 @@ async function automationCheckCommand(checkRunId, options) {
|
|
|
31545
32032
|
`/v1/automations/checks/${id}`,
|
|
31546
32033
|
{ method: "POST", body }
|
|
31547
32034
|
);
|
|
31548
|
-
console.log(response.reported ?
|
|
32035
|
+
console.log(response.reported ? import_chalk20.default.green(`
|
|
31549
32036
|
Reported ${conclusion} for "${response.name}".
|
|
31550
|
-
`) :
|
|
32037
|
+
`) : import_chalk20.default.yellow(`
|
|
31551
32038
|
Skipped "${response.name}" \u2014 a newer run of this automation owns it and will report the verdict.
|
|
31552
32039
|
`));
|
|
31553
32040
|
} catch (error51) {
|
|
31554
|
-
console.error(
|
|
32041
|
+
console.error(import_chalk20.default.red(`Error: ${error51 instanceof Error ? error51.message : "Unknown error"}`));
|
|
31555
32042
|
process.exit(1);
|
|
31556
32043
|
}
|
|
31557
32044
|
}
|
|
31558
32045
|
|
|
31559
32046
|
// src/commands/preview.ts
|
|
31560
|
-
var
|
|
32047
|
+
var import_chalk21 = __toESM(require("chalk"));
|
|
31561
32048
|
|
|
31562
32049
|
// src/lib/agent-api.ts
|
|
31563
32050
|
var ENGINE_PORT = process.env.REPLICAS_ENGINE_PORT || "3737";
|
|
31564
|
-
async function agentFetch(
|
|
32051
|
+
async function agentFetch(path7, options) {
|
|
31565
32052
|
const config3 = readAgentConfig();
|
|
31566
32053
|
if (!config3) {
|
|
31567
32054
|
throw new Error("Agent mode config not found");
|
|
@@ -31575,7 +32062,7 @@ async function agentFetch(path6, options) {
|
|
|
31575
32062
|
...options?.headers || {}
|
|
31576
32063
|
};
|
|
31577
32064
|
const body = options?.body === void 0 ? void 0 : isFormData ? options.body : JSON.stringify(options.body);
|
|
31578
|
-
const response = await fetch(`${MONOLITH_URL}${
|
|
32065
|
+
const response = await fetch(`${MONOLITH_URL}${path7}`, {
|
|
31579
32066
|
...options,
|
|
31580
32067
|
headers,
|
|
31581
32068
|
body
|
|
@@ -31586,7 +32073,7 @@ async function agentFetch(path6, options) {
|
|
|
31586
32073
|
}
|
|
31587
32074
|
return response.json();
|
|
31588
32075
|
}
|
|
31589
|
-
async function engineFetch(
|
|
32076
|
+
async function engineFetch(path7, options) {
|
|
31590
32077
|
const config3 = readAgentConfig();
|
|
31591
32078
|
if (!config3) {
|
|
31592
32079
|
throw new Error("Agent mode config not found");
|
|
@@ -31596,7 +32083,7 @@ async function engineFetch(path6, options) {
|
|
|
31596
32083
|
"Content-Type": "application/json",
|
|
31597
32084
|
...options?.headers || {}
|
|
31598
32085
|
};
|
|
31599
|
-
const response = await fetch(`http://localhost:${ENGINE_PORT}${
|
|
32086
|
+
const response = await fetch(`http://localhost:${ENGINE_PORT}${path7}`, {
|
|
31600
32087
|
...options,
|
|
31601
32088
|
headers,
|
|
31602
32089
|
body: options?.body !== void 0 ? JSON.stringify(options.body) : void 0
|
|
@@ -31651,11 +32138,11 @@ async function previewListCommand(workspaceId) {
|
|
|
31651
32138
|
`/v1/workspaces/${workspaceId}/previews`
|
|
31652
32139
|
);
|
|
31653
32140
|
if (result.previews.length === 0) {
|
|
31654
|
-
console.log(
|
|
32141
|
+
console.log(import_chalk21.default.dim("No active previews"));
|
|
31655
32142
|
return;
|
|
31656
32143
|
}
|
|
31657
32144
|
for (const preview2 of result.previews) {
|
|
31658
|
-
console.log(` ${
|
|
32145
|
+
console.log(` ${import_chalk21.default.cyan(String(preview2.port))} \u2192 ${import_chalk21.default.underline(preview2.publicUrl)}`);
|
|
31659
32146
|
}
|
|
31660
32147
|
}
|
|
31661
32148
|
}
|
|
@@ -31668,7 +32155,7 @@ async function previewAddCommand(workspaceId, options) {
|
|
|
31668
32155
|
body: { port: portNum, authenticated: options.authenticated ?? false }
|
|
31669
32156
|
}
|
|
31670
32157
|
);
|
|
31671
|
-
console.log(
|
|
32158
|
+
console.log(import_chalk21.default.green(`Preview created: ${result.preview.publicUrl}`));
|
|
31672
32159
|
}
|
|
31673
32160
|
async function previewDeleteCommand(port) {
|
|
31674
32161
|
const portNum = parsePreviewPort(port);
|
|
@@ -31681,12 +32168,12 @@ async function previewRemoveCommand(workspaceId, options) {
|
|
|
31681
32168
|
`/v1/workspaces/${workspaceId}/previews/${portNum}`,
|
|
31682
32169
|
{ method: "DELETE" }
|
|
31683
32170
|
);
|
|
31684
|
-
console.log(
|
|
32171
|
+
console.log(import_chalk21.default.green(`Preview deleted on port ${portNum}`));
|
|
31685
32172
|
}
|
|
31686
32173
|
|
|
31687
32174
|
// src/commands/media.ts
|
|
31688
|
-
var
|
|
31689
|
-
var
|
|
32175
|
+
var import_fs5 = __toESM(require("fs"));
|
|
32176
|
+
var import_path6 = __toESM(require("path"));
|
|
31690
32177
|
var MEDIA_ACCESS_VALUES = ["organization", "public"];
|
|
31691
32178
|
function publicMediaUrl(mediaId, token) {
|
|
31692
32179
|
return `${MONOLITH_URL}/v1/media/public/${mediaId}/${token}`;
|
|
@@ -31726,22 +32213,22 @@ function resolveKind(ext, override) {
|
|
|
31726
32213
|
return inferred;
|
|
31727
32214
|
}
|
|
31728
32215
|
async function uploadOne(filePath, displayName, kind, options) {
|
|
31729
|
-
const absPath =
|
|
31730
|
-
if (!
|
|
32216
|
+
const absPath = import_path6.default.resolve(filePath);
|
|
32217
|
+
if (!import_fs5.default.existsSync(absPath)) {
|
|
31731
32218
|
throw new Error(`File not found: ${absPath}`);
|
|
31732
32219
|
}
|
|
31733
|
-
const stat =
|
|
32220
|
+
const stat = import_fs5.default.statSync(absPath);
|
|
31734
32221
|
if (!stat.isFile()) {
|
|
31735
32222
|
throw new Error(`Not a file: ${absPath}`);
|
|
31736
32223
|
}
|
|
31737
32224
|
if (stat.size === 0) {
|
|
31738
32225
|
throw new Error("File is empty");
|
|
31739
32226
|
}
|
|
31740
|
-
const fileName =
|
|
31741
|
-
const ext =
|
|
32227
|
+
const fileName = import_path6.default.basename(absPath);
|
|
32228
|
+
const ext = import_path6.default.extname(absPath).slice(1).toLowerCase();
|
|
31742
32229
|
const contentType = mediaInfo(ext)?.contentType ?? "application/octet-stream";
|
|
31743
32230
|
const form = new FormData();
|
|
31744
|
-
form.append("file", new Blob([
|
|
32231
|
+
form.append("file", new Blob([import_fs5.default.readFileSync(absPath)], { type: contentType }), fileName);
|
|
31745
32232
|
form.append("kind", kind);
|
|
31746
32233
|
if (options.sessionId) form.append("session_id", options.sessionId);
|
|
31747
32234
|
form.append("display_name", displayName);
|
|
@@ -31775,7 +32262,7 @@ async function mediaUploadCommand(filePaths, options) {
|
|
|
31775
32262
|
}
|
|
31776
32263
|
const publicAccess = options.share || options.access === "public";
|
|
31777
32264
|
const kinds = filePaths.map((filePath) => {
|
|
31778
|
-
const ext =
|
|
32265
|
+
const ext = import_path6.default.extname(filePath).slice(1).toLowerCase();
|
|
31779
32266
|
return resolveKind(ext, options.kind);
|
|
31780
32267
|
});
|
|
31781
32268
|
if (publicAccess && kinds.some((kind) => !isPublicMediaKind(kind))) {
|
|
@@ -31861,7 +32348,7 @@ async function mediaListCommand(options) {
|
|
|
31861
32348
|
}
|
|
31862
32349
|
|
|
31863
32350
|
// src/commands/slack.ts
|
|
31864
|
-
var
|
|
32351
|
+
var import_chalk22 = __toESM(require("chalk"));
|
|
31865
32352
|
function getThreadOptions(options) {
|
|
31866
32353
|
const channelId = options.channel || process.env.REPLICAS_SLACK_CHANNEL_ID || process.env.SLACK_CHANNEL_ID;
|
|
31867
32354
|
const threadTs = options.threadTs || process.env.REPLICAS_SLACK_THREAD_TS || process.env.SLACK_THREAD_TS;
|
|
@@ -31878,10 +32365,10 @@ async function attachThread(request) {
|
|
|
31878
32365
|
method: "POST",
|
|
31879
32366
|
body: request
|
|
31880
32367
|
});
|
|
31881
|
-
console.log(
|
|
31882
|
-
console.log(
|
|
31883
|
-
console.log(
|
|
31884
|
-
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})`));
|
|
31885
32372
|
}
|
|
31886
32373
|
async function slackThreadAttachCommand(options) {
|
|
31887
32374
|
const agentConfig = readAgentConfig();
|
|
@@ -31910,7 +32397,7 @@ async function slackThreadSwitchCommand(workspace, options) {
|
|
|
31910
32397
|
}
|
|
31911
32398
|
|
|
31912
32399
|
// src/commands/service.ts
|
|
31913
|
-
var
|
|
32400
|
+
var import_chalk23 = __toESM(require("chalk"));
|
|
31914
32401
|
var import_node_child_process2 = require("child_process");
|
|
31915
32402
|
var import_node_fs2 = require("fs");
|
|
31916
32403
|
var import_node_os2 = require("os");
|
|
@@ -32053,7 +32540,7 @@ async function serviceListCommand() {
|
|
|
32053
32540
|
return;
|
|
32054
32541
|
}
|
|
32055
32542
|
for (const state of states) {
|
|
32056
|
-
const status = isRunning(state.pid) ?
|
|
32543
|
+
const status = isRunning(state.pid) ? import_chalk23.default.green("running") : import_chalk23.default.red("stopped");
|
|
32057
32544
|
console.log(`${state.name} ${status} pid ${state.pid} started ${state.startedAt}`);
|
|
32058
32545
|
console.log(` command: ${state.command} (cwd: ${state.cwd})`);
|
|
32059
32546
|
console.log(` logs: ${state.logFile}`);
|
|
@@ -32159,8 +32646,8 @@ Workspace: ${workspaceNameForOutput(result.workspace_name)} (${getWorkspaceDashb
|
|
|
32159
32646
|
}
|
|
32160
32647
|
|
|
32161
32648
|
// src/commands/environment.ts
|
|
32162
|
-
var
|
|
32163
|
-
var
|
|
32649
|
+
var import_fs6 = __toESM(require("fs"));
|
|
32650
|
+
var import_chalk24 = __toESM(require("chalk"));
|
|
32164
32651
|
var import_prompts8 = __toESM(require("prompts"));
|
|
32165
32652
|
function maskValue(value) {
|
|
32166
32653
|
if (value.length <= 4) return "\u2022\u2022\u2022\u2022";
|
|
@@ -32172,38 +32659,38 @@ async function resolveEnvironmentId(input) {
|
|
|
32172
32659
|
const response = await orgAuthenticatedFetch("/v1/environments");
|
|
32173
32660
|
const resolved = resolveByNameOrId(input, response.environments);
|
|
32174
32661
|
if (!resolved) {
|
|
32175
|
-
console.log(
|
|
32662
|
+
console.log(import_chalk24.default.red(`Environment not found: ${input}`));
|
|
32176
32663
|
const available = response.environments.map((e) => e.name).join(", ");
|
|
32177
|
-
console.log(
|
|
32664
|
+
console.log(import_chalk24.default.gray(`Available: ${available || "(none)"}`));
|
|
32178
32665
|
process.exit(1);
|
|
32179
32666
|
}
|
|
32180
32667
|
return resolved.id;
|
|
32181
32668
|
}
|
|
32182
32669
|
function printEnvironment(env) {
|
|
32183
|
-
console.log(
|
|
32184
|
-
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}`));
|
|
32185
32672
|
if (env.description) {
|
|
32186
|
-
console.log(
|
|
32673
|
+
console.log(import_chalk24.default.gray(` Description: ${env.description}`));
|
|
32187
32674
|
}
|
|
32188
32675
|
if (env.repository_id) {
|
|
32189
|
-
console.log(
|
|
32676
|
+
console.log(import_chalk24.default.gray(` Repository: ${env.repository_id}`));
|
|
32190
32677
|
} else if (env.repository_set_id) {
|
|
32191
|
-
console.log(
|
|
32678
|
+
console.log(import_chalk24.default.gray(` Repository Set: ${env.repository_set_id}`));
|
|
32192
32679
|
}
|
|
32193
32680
|
if (env.variable_count !== void 0) {
|
|
32194
|
-
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}`));
|
|
32195
32682
|
}
|
|
32196
|
-
console.log(
|
|
32683
|
+
console.log(import_chalk24.default.gray(` Updated: ${formatDate2(env.updated_at)}`));
|
|
32197
32684
|
console.log();
|
|
32198
32685
|
}
|
|
32199
32686
|
async function environmentListCommand() {
|
|
32200
32687
|
ensureOrgApiAuthenticated();
|
|
32201
32688
|
const response = await orgAuthenticatedFetch("/v1/environments");
|
|
32202
32689
|
if (response.environments.length === 0) {
|
|
32203
|
-
console.log(
|
|
32690
|
+
console.log(import_chalk24.default.yellow("\nNo environments found.\n"));
|
|
32204
32691
|
return;
|
|
32205
32692
|
}
|
|
32206
|
-
console.log(
|
|
32693
|
+
console.log(import_chalk24.default.green(`
|
|
32207
32694
|
Environments (${response.environments.length}):
|
|
32208
32695
|
`));
|
|
32209
32696
|
for (const env of response.environments) {
|
|
@@ -32214,7 +32701,7 @@ async function environmentGetCommand(idOrName) {
|
|
|
32214
32701
|
ensureOrgApiAuthenticated();
|
|
32215
32702
|
const id = await resolveEnvironmentId(idOrName);
|
|
32216
32703
|
const response = await orgAuthenticatedFetch(`/v1/environments/${id}`);
|
|
32217
|
-
console.log(
|
|
32704
|
+
console.log(import_chalk24.default.green(`
|
|
32218
32705
|
Environment: ${response.environment.name}
|
|
32219
32706
|
`));
|
|
32220
32707
|
printEnvironment(response.environment);
|
|
@@ -32230,7 +32717,7 @@ async function environmentCreateCommand(name, options) {
|
|
|
32230
32717
|
validate: (v) => v.trim() ? true : "Name is required"
|
|
32231
32718
|
});
|
|
32232
32719
|
if (!r.name) {
|
|
32233
|
-
console.log(
|
|
32720
|
+
console.log(import_chalk24.default.yellow("\nCancelled."));
|
|
32234
32721
|
return;
|
|
32235
32722
|
}
|
|
32236
32723
|
envName = r.name;
|
|
@@ -32243,8 +32730,8 @@ async function environmentCreateCommand(name, options) {
|
|
|
32243
32730
|
const repos2 = await orgAuthenticatedFetch("/v1/repositories");
|
|
32244
32731
|
const repo = repos2.repositories.find((r) => r.name === options.repository);
|
|
32245
32732
|
if (!repo) {
|
|
32246
|
-
console.log(
|
|
32247
|
-
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(", ")}`));
|
|
32248
32735
|
process.exit(1);
|
|
32249
32736
|
}
|
|
32250
32737
|
repositoryId = repo.id;
|
|
@@ -32274,9 +32761,9 @@ async function environmentCreateCommand(name, options) {
|
|
|
32274
32761
|
method: "POST",
|
|
32275
32762
|
body
|
|
32276
32763
|
});
|
|
32277
|
-
console.log(
|
|
32764
|
+
console.log(import_chalk24.default.green(`
|
|
32278
32765
|
Created environment: ${response.environment.name}`));
|
|
32279
|
-
console.log(
|
|
32766
|
+
console.log(import_chalk24.default.gray(` ID: ${response.environment.id}
|
|
32280
32767
|
`));
|
|
32281
32768
|
}
|
|
32282
32769
|
async function environmentEditCommand(idOrName, options) {
|
|
@@ -32295,21 +32782,21 @@ async function environmentEditCommand(idOrName, options) {
|
|
|
32295
32782
|
const repos2 = await orgAuthenticatedFetch("/v1/repositories");
|
|
32296
32783
|
const repo = repos2.repositories.find((r) => r.name === options.repository);
|
|
32297
32784
|
if (!repo) {
|
|
32298
|
-
console.log(
|
|
32785
|
+
console.log(import_chalk24.default.red(`Repository not found: ${options.repository}`));
|
|
32299
32786
|
process.exit(1);
|
|
32300
32787
|
}
|
|
32301
32788
|
body.repository_id = repo.id;
|
|
32302
32789
|
}
|
|
32303
32790
|
}
|
|
32304
32791
|
if (Object.keys(body).length === 0) {
|
|
32305
|
-
console.log(
|
|
32792
|
+
console.log(import_chalk24.default.yellow("\nNo changes specified. Pass --name, --description, --repository, or --system-prompt."));
|
|
32306
32793
|
return;
|
|
32307
32794
|
}
|
|
32308
32795
|
const response = await orgAuthenticatedFetch(`/v1/environments/${id}`, {
|
|
32309
32796
|
method: "PATCH",
|
|
32310
32797
|
body
|
|
32311
32798
|
});
|
|
32312
|
-
console.log(
|
|
32799
|
+
console.log(import_chalk24.default.green(`
|
|
32313
32800
|
Updated environment: ${response.environment.name}
|
|
32314
32801
|
`));
|
|
32315
32802
|
}
|
|
@@ -32324,20 +32811,20 @@ async function environmentDeleteCommand(idOrName, options) {
|
|
|
32324
32811
|
initial: false
|
|
32325
32812
|
});
|
|
32326
32813
|
if (!r.confirm) {
|
|
32327
|
-
console.log(
|
|
32814
|
+
console.log(import_chalk24.default.yellow("\nCancelled."));
|
|
32328
32815
|
return;
|
|
32329
32816
|
}
|
|
32330
32817
|
}
|
|
32331
32818
|
await orgAuthenticatedFetch(`/v1/environments/${id}`, { method: "DELETE" });
|
|
32332
|
-
console.log(
|
|
32819
|
+
console.log(import_chalk24.default.green(`
|
|
32333
32820
|
Deleted environment ${idOrName}.
|
|
32334
32821
|
`));
|
|
32335
32822
|
}
|
|
32336
32823
|
function printVariable(v, reveal) {
|
|
32337
|
-
console.log(
|
|
32338
|
-
console.log(
|
|
32339
|
-
console.log(
|
|
32340
|
-
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)}`));
|
|
32341
32828
|
console.log();
|
|
32342
32829
|
}
|
|
32343
32830
|
async function envVarsListCommand(envIdOrName, options) {
|
|
@@ -32347,14 +32834,14 @@ async function envVarsListCommand(envIdOrName, options) {
|
|
|
32347
32834
|
`/v1/environments/${id}/variables`
|
|
32348
32835
|
);
|
|
32349
32836
|
if (response.environment_variables.length === 0) {
|
|
32350
|
-
console.log(
|
|
32837
|
+
console.log(import_chalk24.default.yellow("\nNo variables.\n"));
|
|
32351
32838
|
return;
|
|
32352
32839
|
}
|
|
32353
|
-
console.log(
|
|
32840
|
+
console.log(import_chalk24.default.green(`
|
|
32354
32841
|
Variables (${response.environment_variables.length}):
|
|
32355
32842
|
`));
|
|
32356
32843
|
if (!options.reveal) {
|
|
32357
|
-
console.log(
|
|
32844
|
+
console.log(import_chalk24.default.gray(" Values are masked. Pass --reveal to show full values.\n"));
|
|
32358
32845
|
}
|
|
32359
32846
|
for (const v of response.environment_variables) printVariable(v, !!options.reveal);
|
|
32360
32847
|
}
|
|
@@ -32371,7 +32858,7 @@ async function envVarsSetCommand(envIdOrName, key, value) {
|
|
|
32371
32858
|
`/v1/environments/${id}/variables/${match.id}`,
|
|
32372
32859
|
{ method: "PATCH", body: body2 }
|
|
32373
32860
|
);
|
|
32374
|
-
console.log(
|
|
32861
|
+
console.log(import_chalk24.default.green(`
|
|
32375
32862
|
Updated variable ${response2.environment_variable.key}.
|
|
32376
32863
|
`));
|
|
32377
32864
|
return;
|
|
@@ -32385,7 +32872,7 @@ Updated variable ${response2.environment_variable.key}.
|
|
|
32385
32872
|
`/v1/environments/${id}/variables`,
|
|
32386
32873
|
{ method: "POST", body }
|
|
32387
32874
|
);
|
|
32388
|
-
console.log(
|
|
32875
|
+
console.log(import_chalk24.default.green(`
|
|
32389
32876
|
Created variable ${response.environment_variable.key}.
|
|
32390
32877
|
`));
|
|
32391
32878
|
}
|
|
@@ -32399,7 +32886,7 @@ async function envVarsDeleteCommand(envIdOrName, keyOrId, options) {
|
|
|
32399
32886
|
);
|
|
32400
32887
|
const match = existing.environment_variables.find((v) => v.key === keyOrId);
|
|
32401
32888
|
if (!match) {
|
|
32402
|
-
console.log(
|
|
32889
|
+
console.log(import_chalk24.default.red(`Variable not found: ${keyOrId}`));
|
|
32403
32890
|
process.exit(1);
|
|
32404
32891
|
}
|
|
32405
32892
|
variableId = match.id;
|
|
@@ -32412,23 +32899,23 @@ async function envVarsDeleteCommand(envIdOrName, keyOrId, options) {
|
|
|
32412
32899
|
initial: false
|
|
32413
32900
|
});
|
|
32414
32901
|
if (!r.confirm) {
|
|
32415
|
-
console.log(
|
|
32902
|
+
console.log(import_chalk24.default.yellow("\nCancelled."));
|
|
32416
32903
|
return;
|
|
32417
32904
|
}
|
|
32418
32905
|
}
|
|
32419
32906
|
await orgAuthenticatedFetch(`/v1/environments/${id}/variables/${variableId}`, {
|
|
32420
32907
|
method: "DELETE"
|
|
32421
32908
|
});
|
|
32422
|
-
console.log(
|
|
32909
|
+
console.log(import_chalk24.default.green(`
|
|
32423
32910
|
Deleted variable ${keyOrId}.
|
|
32424
32911
|
`));
|
|
32425
32912
|
}
|
|
32426
32913
|
function printFile(f) {
|
|
32427
|
-
console.log(
|
|
32428
|
-
console.log(
|
|
32429
|
-
console.log(
|
|
32430
|
-
console.log(
|
|
32431
|
-
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)}`));
|
|
32432
32919
|
console.log();
|
|
32433
32920
|
}
|
|
32434
32921
|
async function envFilesListCommand(envIdOrName) {
|
|
@@ -32438,20 +32925,20 @@ async function envFilesListCommand(envIdOrName) {
|
|
|
32438
32925
|
`/v1/environments/${id}/files`
|
|
32439
32926
|
);
|
|
32440
32927
|
if (response.environment_files.length === 0) {
|
|
32441
|
-
console.log(
|
|
32928
|
+
console.log(import_chalk24.default.yellow("\nNo files.\n"));
|
|
32442
32929
|
return;
|
|
32443
32930
|
}
|
|
32444
|
-
console.log(
|
|
32931
|
+
console.log(import_chalk24.default.green(`
|
|
32445
32932
|
Files (${response.environment_files.length}):
|
|
32446
32933
|
`));
|
|
32447
32934
|
for (const f of response.environment_files) printFile(f);
|
|
32448
32935
|
}
|
|
32449
32936
|
function readFileContent(options) {
|
|
32450
32937
|
if (options.file) {
|
|
32451
|
-
if (!
|
|
32938
|
+
if (!import_fs6.default.existsSync(options.file)) {
|
|
32452
32939
|
throw new Error(`Local file not found: ${options.file}`);
|
|
32453
32940
|
}
|
|
32454
|
-
return
|
|
32941
|
+
return import_fs6.default.readFileSync(options.file, "utf-8");
|
|
32455
32942
|
}
|
|
32456
32943
|
if (options.content !== void 0) return options.content;
|
|
32457
32944
|
throw new Error('Pass either --content "..." or --file <local-path>');
|
|
@@ -32472,7 +32959,7 @@ async function envFilesSetCommand(envIdOrName, destinationPath, options) {
|
|
|
32472
32959
|
`/v1/environments/${id}/files/${match.id}`,
|
|
32473
32960
|
{ method: "PATCH", body: body2 }
|
|
32474
32961
|
);
|
|
32475
|
-
console.log(
|
|
32962
|
+
console.log(import_chalk24.default.green(`
|
|
32476
32963
|
Updated file ${response2.environment_file.path}.
|
|
32477
32964
|
`));
|
|
32478
32965
|
return;
|
|
@@ -32487,7 +32974,7 @@ Updated file ${response2.environment_file.path}.
|
|
|
32487
32974
|
`/v1/environments/${id}/files`,
|
|
32488
32975
|
{ method: "POST", body }
|
|
32489
32976
|
);
|
|
32490
|
-
console.log(
|
|
32977
|
+
console.log(import_chalk24.default.green(`
|
|
32491
32978
|
Created file ${response.environment_file.path}.
|
|
32492
32979
|
`));
|
|
32493
32980
|
}
|
|
@@ -32501,7 +32988,7 @@ async function envFilesDeleteCommand(envIdOrName, pathOrId, options) {
|
|
|
32501
32988
|
);
|
|
32502
32989
|
const match = existing.environment_files.find((f) => f.path === pathOrId);
|
|
32503
32990
|
if (!match) {
|
|
32504
|
-
console.log(
|
|
32991
|
+
console.log(import_chalk24.default.red(`File not found: ${pathOrId}`));
|
|
32505
32992
|
process.exit(1);
|
|
32506
32993
|
}
|
|
32507
32994
|
fileId = match.id;
|
|
@@ -32514,14 +33001,14 @@ async function envFilesDeleteCommand(envIdOrName, pathOrId, options) {
|
|
|
32514
33001
|
initial: false
|
|
32515
33002
|
});
|
|
32516
33003
|
if (!r.confirm) {
|
|
32517
|
-
console.log(
|
|
33004
|
+
console.log(import_chalk24.default.yellow("\nCancelled."));
|
|
32518
33005
|
return;
|
|
32519
33006
|
}
|
|
32520
33007
|
}
|
|
32521
33008
|
await orgAuthenticatedFetch(`/v1/environments/${id}/files/${fileId}`, {
|
|
32522
33009
|
method: "DELETE"
|
|
32523
33010
|
});
|
|
32524
|
-
console.log(
|
|
33011
|
+
console.log(import_chalk24.default.green(`
|
|
32525
33012
|
Deleted file ${pathOrId}.
|
|
32526
33013
|
`));
|
|
32527
33014
|
}
|
|
@@ -32530,16 +33017,16 @@ async function envHookGetCommand(envIdOrName, kind) {
|
|
|
32530
33017
|
const id = await resolveEnvironmentId(envIdOrName);
|
|
32531
33018
|
const hook = kind === "warm" ? (await orgAuthenticatedFetch(`/v1/environments/${id}/warm-hooks`)).warm_hook : (await orgAuthenticatedFetch(`/v1/environments/${id}/start-hooks`)).start_hook;
|
|
32532
33019
|
if (!hook) {
|
|
32533
|
-
console.log(
|
|
33020
|
+
console.log(import_chalk24.default.yellow(`
|
|
32534
33021
|
No ${kind} hook configured.
|
|
32535
33022
|
`));
|
|
32536
33023
|
return;
|
|
32537
33024
|
}
|
|
32538
|
-
console.log(
|
|
33025
|
+
console.log(import_chalk24.default.green(`
|
|
32539
33026
|
${kind === "warm" ? "Warm" : "Start"} hook (v${hook.version}, ${hook.is_active ? "active" : "inactive"}):
|
|
32540
33027
|
`));
|
|
32541
|
-
console.log(
|
|
32542
|
-
console.log(
|
|
33028
|
+
console.log(import_chalk24.default.gray(` ID: ${hook.id}`));
|
|
33029
|
+
console.log(import_chalk24.default.gray(` Created: ${formatDate2(hook.created_at)}
|
|
32543
33030
|
`));
|
|
32544
33031
|
console.log(hook.content);
|
|
32545
33032
|
console.log();
|
|
@@ -32554,7 +33041,7 @@ async function envHookSaveCommand(envIdOrName, options, kind) {
|
|
|
32554
33041
|
`/v1/environments/${id}/warm-hooks/save`,
|
|
32555
33042
|
{ method: "POST", body: body2 }
|
|
32556
33043
|
);
|
|
32557
|
-
console.log(
|
|
33044
|
+
console.log(import_chalk24.default.green(`
|
|
32558
33045
|
Saved warm hook v${response2.warm_hook.version}.
|
|
32559
33046
|
`));
|
|
32560
33047
|
return;
|
|
@@ -32564,7 +33051,7 @@ Saved warm hook v${response2.warm_hook.version}.
|
|
|
32564
33051
|
`/v1/environments/${id}/start-hooks/save`,
|
|
32565
33052
|
{ method: "POST", body }
|
|
32566
33053
|
);
|
|
32567
|
-
console.log(
|
|
33054
|
+
console.log(import_chalk24.default.green(response.start_hook ? `
|
|
32568
33055
|
Saved start hook v${response.start_hook.version}.
|
|
32569
33056
|
` : "\nCleared start hook.\n"));
|
|
32570
33057
|
}
|
|
@@ -32581,7 +33068,7 @@ async function envHookTestCommand(envIdOrName, options, kind) {
|
|
|
32581
33068
|
body: kind === "warm" ? { content, mode: options.save ? "save_test" : "test_only" } : { content },
|
|
32582
33069
|
onEvent: (event) => {
|
|
32583
33070
|
if (event.type === "progress" && event.message) {
|
|
32584
|
-
console.log(
|
|
33071
|
+
console.log(import_chalk24.default.gray(event.message));
|
|
32585
33072
|
} else if (event.type === "output" && event.output) {
|
|
32586
33073
|
process.stdout.write(event.output);
|
|
32587
33074
|
} else if (event.type === "complete") {
|
|
@@ -32594,23 +33081,23 @@ async function envHookTestCommand(envIdOrName, options, kind) {
|
|
|
32594
33081
|
}
|
|
32595
33082
|
);
|
|
32596
33083
|
if (errorMessage) {
|
|
32597
|
-
console.log(
|
|
33084
|
+
console.log(import_chalk24.default.red(`
|
|
32598
33085
|
${errorMessage}
|
|
32599
33086
|
`));
|
|
32600
33087
|
process.exit(1);
|
|
32601
33088
|
}
|
|
32602
33089
|
if (timedOut) {
|
|
32603
|
-
console.log(
|
|
33090
|
+
console.log(import_chalk24.default.yellow(`
|
|
32604
33091
|
${kind === "warm" ? "Warm" : "Start"} hook timed out.
|
|
32605
33092
|
`));
|
|
32606
33093
|
process.exit(1);
|
|
32607
33094
|
}
|
|
32608
33095
|
if (exitCode === 0) {
|
|
32609
|
-
console.log(
|
|
33096
|
+
console.log(import_chalk24.default.green(`
|
|
32610
33097
|
${kind === "warm" ? "Warm" : "Start"} hook passed${options.save ? " and was saved" : ""} (exit code ${exitCode}).
|
|
32611
33098
|
`));
|
|
32612
33099
|
} else {
|
|
32613
|
-
console.log(
|
|
33100
|
+
console.log(import_chalk24.default.red(`
|
|
32614
33101
|
${kind === "warm" ? "Warm" : "Start"} hook failed (exit code ${exitCode ?? "unknown"}).
|
|
32615
33102
|
`));
|
|
32616
33103
|
process.exit(1);
|
|
@@ -32625,24 +33112,24 @@ async function envHookRepositoryHooksCommand(envIdOrName, kind) {
|
|
|
32625
33112
|
`/v1/environments/${id}/start-hooks/repository-hooks`
|
|
32626
33113
|
)).repositories.map((repository) => ({ ...repository, hook: repository.start_hook }));
|
|
32627
33114
|
if (repositories.length === 0) {
|
|
32628
|
-
console.log(
|
|
33115
|
+
console.log(import_chalk24.default.yellow("\nNo repositories bound to this environment.\n"));
|
|
32629
33116
|
return;
|
|
32630
33117
|
}
|
|
32631
|
-
console.log(
|
|
33118
|
+
console.log(import_chalk24.default.green(`
|
|
32632
33119
|
Repository ${kind} hooks (${repositories.length}):
|
|
32633
33120
|
`));
|
|
32634
33121
|
for (const repo of repositories) {
|
|
32635
|
-
console.log(
|
|
33122
|
+
console.log(import_chalk24.default.white(` ${repo.repository_name} @${repo.default_branch}`));
|
|
32636
33123
|
if (repo.error) {
|
|
32637
|
-
console.log(
|
|
33124
|
+
console.log(import_chalk24.default.red(` Error: ${repo.error}`));
|
|
32638
33125
|
} else if (repo.hook) {
|
|
32639
|
-
console.log(
|
|
32640
|
-
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}):`));
|
|
32641
33128
|
for (const cmd of repo.hook.commands) {
|
|
32642
|
-
console.log(
|
|
33129
|
+
console.log(import_chalk24.default.gray(` ${cmd}`));
|
|
32643
33130
|
}
|
|
32644
33131
|
} else {
|
|
32645
|
-
console.log(
|
|
33132
|
+
console.log(import_chalk24.default.gray(` No ${kind}Hook defined.`));
|
|
32646
33133
|
}
|
|
32647
33134
|
console.log();
|
|
32648
33135
|
}
|
|
@@ -32707,7 +33194,7 @@ program.hook("preAction", async (_command, actionCommand) => {
|
|
|
32707
33194
|
throw new Error('No organization selected. Run "replicas org switch" to select one.');
|
|
32708
33195
|
}
|
|
32709
33196
|
} catch (error51) {
|
|
32710
|
-
console.error(
|
|
33197
|
+
console.error(import_chalk25.default.red(`
|
|
32711
33198
|
\u2717 ${error51 instanceof Error ? error51.message : "Unknown error"}
|
|
32712
33199
|
`));
|
|
32713
33200
|
process.exit(1);
|
|
@@ -32721,7 +33208,7 @@ function registerSlackCommands(parent) {
|
|
|
32721
33208
|
await slackThreadAttachCommand(options);
|
|
32722
33209
|
} catch (error51) {
|
|
32723
33210
|
if (error51 instanceof Error) {
|
|
32724
|
-
console.error(
|
|
33211
|
+
console.error(import_chalk25.default.red(`
|
|
32725
33212
|
\u2717 ${error51.message}
|
|
32726
33213
|
`));
|
|
32727
33214
|
}
|
|
@@ -32733,7 +33220,7 @@ function registerSlackCommands(parent) {
|
|
|
32733
33220
|
await slackThreadSwitchCommand(workspace, options);
|
|
32734
33221
|
} catch (error51) {
|
|
32735
33222
|
if (error51 instanceof Error) {
|
|
32736
|
-
console.error(
|
|
33223
|
+
console.error(import_chalk25.default.red(`
|
|
32737
33224
|
\u2717 ${error51.message}
|
|
32738
33225
|
`));
|
|
32739
33226
|
}
|
|
@@ -32747,7 +33234,7 @@ program.command("login").description("Authenticate with your Replicas account").
|
|
|
32747
33234
|
await loginCommand();
|
|
32748
33235
|
} catch (error51) {
|
|
32749
33236
|
if (error51 instanceof Error) {
|
|
32750
|
-
console.error(
|
|
33237
|
+
console.error(import_chalk25.default.red(`
|
|
32751
33238
|
\u2717 ${error51.message}
|
|
32752
33239
|
`));
|
|
32753
33240
|
}
|
|
@@ -32759,7 +33246,7 @@ program.command("init").description("Create a replicas.json or replicas.yaml con
|
|
|
32759
33246
|
initCommand(options);
|
|
32760
33247
|
} catch (error51) {
|
|
32761
33248
|
if (error51 instanceof Error) {
|
|
32762
|
-
console.error(
|
|
33249
|
+
console.error(import_chalk25.default.red(`
|
|
32763
33250
|
\u2717 ${error51.message}
|
|
32764
33251
|
`));
|
|
32765
33252
|
}
|
|
@@ -32771,7 +33258,7 @@ program.command("logout").description("Clear stored credentials").action(() => {
|
|
|
32771
33258
|
logoutCommand();
|
|
32772
33259
|
} catch (error51) {
|
|
32773
33260
|
if (error51 instanceof Error) {
|
|
32774
|
-
console.error(
|
|
33261
|
+
console.error(import_chalk25.default.red(`
|
|
32775
33262
|
\u2717 ${error51.message}
|
|
32776
33263
|
`));
|
|
32777
33264
|
}
|
|
@@ -32782,7 +33269,7 @@ program.command("muse-auth").description("Connect your Muse Code subscription to
|
|
|
32782
33269
|
try {
|
|
32783
33270
|
await museAuthCommand(options);
|
|
32784
33271
|
} catch (error51) {
|
|
32785
|
-
if (error51 instanceof Error) console.error(
|
|
33272
|
+
if (error51 instanceof Error) console.error(import_chalk25.default.red(`
|
|
32786
33273
|
\u2717 ${error51.message}
|
|
32787
33274
|
`));
|
|
32788
33275
|
process.exit(1);
|
|
@@ -32793,7 +33280,7 @@ program.command("whoami").description("Display current authenticated user").acti
|
|
|
32793
33280
|
await whoamiCommand();
|
|
32794
33281
|
} catch (error51) {
|
|
32795
33282
|
if (error51 instanceof Error) {
|
|
32796
|
-
console.error(
|
|
33283
|
+
console.error(import_chalk25.default.red(`
|
|
32797
33284
|
\u2717 ${error51.message}
|
|
32798
33285
|
`));
|
|
32799
33286
|
}
|
|
@@ -32805,7 +33292,7 @@ program.command("codex-auth").description("Connect your Codex credentials to Rep
|
|
|
32805
33292
|
await codexAuthCommand(options);
|
|
32806
33293
|
} catch (error51) {
|
|
32807
33294
|
if (error51 instanceof Error) {
|
|
32808
|
-
console.error(
|
|
33295
|
+
console.error(import_chalk25.default.red(`
|
|
32809
33296
|
\u2717 ${error51.message}
|
|
32810
33297
|
`));
|
|
32811
33298
|
}
|
|
@@ -32817,7 +33304,7 @@ program.command("claude-auth").description("Connect your Claude Code credentials
|
|
|
32817
33304
|
await claudeAuthCommand(options);
|
|
32818
33305
|
} catch (error51) {
|
|
32819
33306
|
if (error51 instanceof Error) {
|
|
32820
|
-
console.error(
|
|
33307
|
+
console.error(import_chalk25.default.red(`
|
|
32821
33308
|
\u2717 ${error51.message}
|
|
32822
33309
|
`));
|
|
32823
33310
|
}
|
|
@@ -32830,7 +33317,7 @@ org.command("switch").description("Switch to a different organization").action(a
|
|
|
32830
33317
|
await orgSwitchCommand();
|
|
32831
33318
|
} catch (error51) {
|
|
32832
33319
|
if (error51 instanceof Error) {
|
|
32833
|
-
console.error(
|
|
33320
|
+
console.error(import_chalk25.default.red(`
|
|
32834
33321
|
\u2717 ${error51.message}
|
|
32835
33322
|
`));
|
|
32836
33323
|
}
|
|
@@ -32842,7 +33329,7 @@ org.action(async () => {
|
|
|
32842
33329
|
await orgCommand();
|
|
32843
33330
|
} catch (error51) {
|
|
32844
33331
|
if (error51 instanceof Error) {
|
|
32845
|
-
console.error(
|
|
33332
|
+
console.error(import_chalk25.default.red(`
|
|
32846
33333
|
\u2717 ${error51.message}
|
|
32847
33334
|
`));
|
|
32848
33335
|
}
|
|
@@ -32854,7 +33341,7 @@ program.command("connect <workspace-name...>").description("Connect to a workspa
|
|
|
32854
33341
|
await connectCommand(workspaceName.join(" "));
|
|
32855
33342
|
} catch (error51) {
|
|
32856
33343
|
if (error51 instanceof Error) {
|
|
32857
|
-
console.error(
|
|
33344
|
+
console.error(import_chalk25.default.red(`
|
|
32858
33345
|
\u2717 ${error51.message}
|
|
32859
33346
|
`));
|
|
32860
33347
|
}
|
|
@@ -32865,7 +33352,7 @@ program.command("tunnel <workspace-name...>").description("Forward a workspace p
|
|
|
32865
33352
|
try {
|
|
32866
33353
|
await tunnelCommand(workspaceName.join(" "), options);
|
|
32867
33354
|
} catch (error51) {
|
|
32868
|
-
console.error(
|
|
33355
|
+
console.error(import_chalk25.default.red(`
|
|
32869
33356
|
Error: ${error51 instanceof Error ? error51.message : "Unknown error"}`));
|
|
32870
33357
|
process.exit(1);
|
|
32871
33358
|
}
|
|
@@ -32875,7 +33362,7 @@ program.command("code [workspace-name...]").description("Open a workspace in VSC
|
|
|
32875
33362
|
await codeCommand(workspaceName.join(" "));
|
|
32876
33363
|
} catch (error51) {
|
|
32877
33364
|
if (error51 instanceof Error) {
|
|
32878
|
-
console.error(
|
|
33365
|
+
console.error(import_chalk25.default.red(`
|
|
32879
33366
|
\u2717 ${error51.message}
|
|
32880
33367
|
`));
|
|
32881
33368
|
}
|
|
@@ -32888,7 +33375,7 @@ config2.command("get <key>").description("Get a configuration value").action(asy
|
|
|
32888
33375
|
await configGetCommand(key);
|
|
32889
33376
|
} catch (error51) {
|
|
32890
33377
|
if (error51 instanceof Error) {
|
|
32891
|
-
console.error(
|
|
33378
|
+
console.error(import_chalk25.default.red(`
|
|
32892
33379
|
\u2717 ${error51.message}
|
|
32893
33380
|
`));
|
|
32894
33381
|
}
|
|
@@ -32900,7 +33387,7 @@ config2.command("set <key> <value>").description("Set a configuration value").ac
|
|
|
32900
33387
|
await configSetCommand(key, value);
|
|
32901
33388
|
} catch (error51) {
|
|
32902
33389
|
if (error51 instanceof Error) {
|
|
32903
|
-
console.error(
|
|
33390
|
+
console.error(import_chalk25.default.red(`
|
|
32904
33391
|
\u2717 ${error51.message}
|
|
32905
33392
|
`));
|
|
32906
33393
|
}
|
|
@@ -32912,7 +33399,7 @@ config2.command("list").description("List all configuration values").action(asyn
|
|
|
32912
33399
|
await configListCommand();
|
|
32913
33400
|
} catch (error51) {
|
|
32914
33401
|
if (error51 instanceof Error) {
|
|
32915
|
-
console.error(
|
|
33402
|
+
console.error(import_chalk25.default.red(`
|
|
32916
33403
|
\u2717 ${error51.message}
|
|
32917
33404
|
`));
|
|
32918
33405
|
}
|
|
@@ -32924,7 +33411,7 @@ program.command("list").description("List all replicas").option("-p, --page <pag
|
|
|
32924
33411
|
await replicaListCommand(options);
|
|
32925
33412
|
} catch (error51) {
|
|
32926
33413
|
if (error51 instanceof Error) {
|
|
32927
|
-
console.error(
|
|
33414
|
+
console.error(import_chalk25.default.red(`
|
|
32928
33415
|
\u2717 ${error51.message}
|
|
32929
33416
|
`));
|
|
32930
33417
|
}
|
|
@@ -32936,7 +33423,7 @@ program.command("get <id>").description("Get replica details by ID").action(asyn
|
|
|
32936
33423
|
await replicaGetCommand(id);
|
|
32937
33424
|
} catch (error51) {
|
|
32938
33425
|
if (error51 instanceof Error) {
|
|
32939
|
-
console.error(
|
|
33426
|
+
console.error(import_chalk25.default.red(`
|
|
32940
33427
|
\u2717 ${error51.message}
|
|
32941
33428
|
`));
|
|
32942
33429
|
}
|
|
@@ -32948,7 +33435,7 @@ program.command("create [name]").description("Create a new replica").option("-m,
|
|
|
32948
33435
|
await replicaCreateCommand(name, options);
|
|
32949
33436
|
} catch (error51) {
|
|
32950
33437
|
if (error51 instanceof Error) {
|
|
32951
|
-
console.error(
|
|
33438
|
+
console.error(import_chalk25.default.red(`
|
|
32952
33439
|
\u2717 ${error51.message}
|
|
32953
33440
|
`));
|
|
32954
33441
|
}
|
|
@@ -32960,7 +33447,7 @@ program.command("send <id>").description("Send a message to a replica").option("
|
|
|
32960
33447
|
await replicaSendCommand(id, options);
|
|
32961
33448
|
} catch (error51) {
|
|
32962
33449
|
if (error51 instanceof Error) {
|
|
32963
|
-
console.error(
|
|
33450
|
+
console.error(import_chalk25.default.red(`
|
|
32964
33451
|
\u2717 ${error51.message}
|
|
32965
33452
|
`));
|
|
32966
33453
|
}
|
|
@@ -32972,7 +33459,7 @@ program.command("delete <id>").description("Delete a replica").option("-f, --for
|
|
|
32972
33459
|
await replicaDeleteCommand(id, options);
|
|
32973
33460
|
} catch (error51) {
|
|
32974
33461
|
if (error51 instanceof Error) {
|
|
32975
|
-
console.error(
|
|
33462
|
+
console.error(import_chalk25.default.red(`
|
|
32976
33463
|
\u2717 ${error51.message}
|
|
32977
33464
|
`));
|
|
32978
33465
|
}
|
|
@@ -32984,7 +33471,7 @@ program.command("read <id>").description("Read conversation history of a replica
|
|
|
32984
33471
|
await replicaReadCommand(id, options);
|
|
32985
33472
|
} catch (error51) {
|
|
32986
33473
|
if (error51 instanceof Error) {
|
|
32987
|
-
console.error(
|
|
33474
|
+
console.error(import_chalk25.default.red(`
|
|
32988
33475
|
\u2717 ${error51.message}
|
|
32989
33476
|
`));
|
|
32990
33477
|
}
|
|
@@ -32997,7 +33484,7 @@ automation.command("list").description("List all automations").option("-p, --pag
|
|
|
32997
33484
|
await automationListCommand(options);
|
|
32998
33485
|
} catch (error51) {
|
|
32999
33486
|
if (error51 instanceof Error) {
|
|
33000
|
-
console.error(
|
|
33487
|
+
console.error(import_chalk25.default.red(`
|
|
33001
33488
|
\u2717 ${error51.message}
|
|
33002
33489
|
`));
|
|
33003
33490
|
}
|
|
@@ -33009,7 +33496,7 @@ automation.command("get <id>").description("Get automation details by ID").actio
|
|
|
33009
33496
|
await automationGetCommand(id);
|
|
33010
33497
|
} catch (error51) {
|
|
33011
33498
|
if (error51 instanceof Error) {
|
|
33012
|
-
console.error(
|
|
33499
|
+
console.error(import_chalk25.default.red(`
|
|
33013
33500
|
\u2717 ${error51.message}
|
|
33014
33501
|
`));
|
|
33015
33502
|
}
|
|
@@ -33024,7 +33511,7 @@ automation.command("create [name]").description("Create a new automation").optio
|
|
|
33024
33511
|
});
|
|
33025
33512
|
} catch (error51) {
|
|
33026
33513
|
if (error51 instanceof Error) {
|
|
33027
|
-
console.error(
|
|
33514
|
+
console.error(import_chalk25.default.red(`
|
|
33028
33515
|
\u2717 ${error51.message}
|
|
33029
33516
|
`));
|
|
33030
33517
|
}
|
|
@@ -33036,7 +33523,7 @@ automation.command("edit <id>").description("Edit an existing automation").optio
|
|
|
33036
33523
|
await automationEditCommand(id, options);
|
|
33037
33524
|
} catch (error51) {
|
|
33038
33525
|
if (error51 instanceof Error) {
|
|
33039
|
-
console.error(
|
|
33526
|
+
console.error(import_chalk25.default.red(`
|
|
33040
33527
|
\u2717 ${error51.message}
|
|
33041
33528
|
`));
|
|
33042
33529
|
}
|
|
@@ -33048,7 +33535,7 @@ automation.command("run <id>").description("Manually trigger an automation (cron
|
|
|
33048
33535
|
await automationRunCommand(id);
|
|
33049
33536
|
} catch (error51) {
|
|
33050
33537
|
if (error51 instanceof Error) {
|
|
33051
|
-
console.error(
|
|
33538
|
+
console.error(import_chalk25.default.red(`
|
|
33052
33539
|
\u2717 ${error51.message}
|
|
33053
33540
|
`));
|
|
33054
33541
|
}
|
|
@@ -33060,7 +33547,7 @@ automation.command("delete <id>").description("Delete an automation").option("-f
|
|
|
33060
33547
|
await automationDeleteCommand(id, options);
|
|
33061
33548
|
} catch (error51) {
|
|
33062
33549
|
if (error51 instanceof Error) {
|
|
33063
|
-
console.error(
|
|
33550
|
+
console.error(import_chalk25.default.red(`
|
|
33064
33551
|
\u2717 ${error51.message}
|
|
33065
33552
|
`));
|
|
33066
33553
|
}
|
|
@@ -33072,7 +33559,7 @@ automation.command("check <checkRunId>").description("Report this automation run
|
|
|
33072
33559
|
await automationCheckCommand(checkRunId, options);
|
|
33073
33560
|
} catch (error51) {
|
|
33074
33561
|
if (error51 instanceof Error) {
|
|
33075
|
-
console.error(
|
|
33562
|
+
console.error(import_chalk25.default.red(`
|
|
33076
33563
|
\u2717 ${error51.message}
|
|
33077
33564
|
`));
|
|
33078
33565
|
}
|
|
@@ -33084,7 +33571,7 @@ automation.action(async () => {
|
|
|
33084
33571
|
await automationListCommand({});
|
|
33085
33572
|
} catch (error51) {
|
|
33086
33573
|
if (error51 instanceof Error) {
|
|
33087
|
-
console.error(
|
|
33574
|
+
console.error(import_chalk25.default.red(`
|
|
33088
33575
|
\u2717 ${error51.message}
|
|
33089
33576
|
`));
|
|
33090
33577
|
}
|
|
@@ -33097,7 +33584,7 @@ repos.command("list").description("List all repositories").action(async () => {
|
|
|
33097
33584
|
await repositoriesListCommand();
|
|
33098
33585
|
} catch (error51) {
|
|
33099
33586
|
if (error51 instanceof Error) {
|
|
33100
|
-
console.error(
|
|
33587
|
+
console.error(import_chalk25.default.red(`
|
|
33101
33588
|
\u2717 ${error51.message}
|
|
33102
33589
|
`));
|
|
33103
33590
|
}
|
|
@@ -33109,7 +33596,7 @@ repos.action(async () => {
|
|
|
33109
33596
|
await repositoriesListCommand();
|
|
33110
33597
|
} catch (error51) {
|
|
33111
33598
|
if (error51 instanceof Error) {
|
|
33112
|
-
console.error(
|
|
33599
|
+
console.error(import_chalk25.default.red(`
|
|
33113
33600
|
\u2717 ${error51.message}
|
|
33114
33601
|
`));
|
|
33115
33602
|
}
|
|
@@ -33122,7 +33609,7 @@ environment.command("list").description("List all environments").action(async ()
|
|
|
33122
33609
|
await environmentListCommand();
|
|
33123
33610
|
} catch (error51) {
|
|
33124
33611
|
if (error51 instanceof Error) {
|
|
33125
|
-
console.error(
|
|
33612
|
+
console.error(import_chalk25.default.red(`
|
|
33126
33613
|
\u2717 ${error51.message}
|
|
33127
33614
|
`));
|
|
33128
33615
|
}
|
|
@@ -33134,7 +33621,7 @@ environment.command("get <id-or-name>").description('Get an environment by ID or
|
|
|
33134
33621
|
await environmentGetCommand(idOrName);
|
|
33135
33622
|
} catch (error51) {
|
|
33136
33623
|
if (error51 instanceof Error) {
|
|
33137
|
-
console.error(
|
|
33624
|
+
console.error(import_chalk25.default.red(`
|
|
33138
33625
|
\u2717 ${error51.message}
|
|
33139
33626
|
`));
|
|
33140
33627
|
}
|
|
@@ -33146,7 +33633,7 @@ environment.command("create [name]").description("Create a new environment").opt
|
|
|
33146
33633
|
await environmentCreateCommand(name, options);
|
|
33147
33634
|
} catch (error51) {
|
|
33148
33635
|
if (error51 instanceof Error) {
|
|
33149
|
-
console.error(
|
|
33636
|
+
console.error(import_chalk25.default.red(`
|
|
33150
33637
|
\u2717 ${error51.message}
|
|
33151
33638
|
`));
|
|
33152
33639
|
}
|
|
@@ -33158,7 +33645,7 @@ environment.command("edit <id-or-name>").description("Edit an environment").opti
|
|
|
33158
33645
|
await environmentEditCommand(idOrName, options);
|
|
33159
33646
|
} catch (error51) {
|
|
33160
33647
|
if (error51 instanceof Error) {
|
|
33161
|
-
console.error(
|
|
33648
|
+
console.error(import_chalk25.default.red(`
|
|
33162
33649
|
\u2717 ${error51.message}
|
|
33163
33650
|
`));
|
|
33164
33651
|
}
|
|
@@ -33170,7 +33657,7 @@ environment.command("delete <id-or-name>").description("Delete an environment").
|
|
|
33170
33657
|
await environmentDeleteCommand(idOrName, options);
|
|
33171
33658
|
} catch (error51) {
|
|
33172
33659
|
if (error51 instanceof Error) {
|
|
33173
|
-
console.error(
|
|
33660
|
+
console.error(import_chalk25.default.red(`
|
|
33174
33661
|
\u2717 ${error51.message}
|
|
33175
33662
|
`));
|
|
33176
33663
|
}
|
|
@@ -33183,7 +33670,7 @@ envVars.command("list <env>").description("List variables in an environment (val
|
|
|
33183
33670
|
await envVarsListCommand(env, options);
|
|
33184
33671
|
} catch (error51) {
|
|
33185
33672
|
if (error51 instanceof Error) {
|
|
33186
|
-
console.error(
|
|
33673
|
+
console.error(import_chalk25.default.red(`
|
|
33187
33674
|
\u2717 ${error51.message}
|
|
33188
33675
|
`));
|
|
33189
33676
|
}
|
|
@@ -33195,7 +33682,7 @@ envVars.command("set <env> <key> <value>").description("Create or update a varia
|
|
|
33195
33682
|
await envVarsSetCommand(env, key, value);
|
|
33196
33683
|
} catch (error51) {
|
|
33197
33684
|
if (error51 instanceof Error) {
|
|
33198
|
-
console.error(
|
|
33685
|
+
console.error(import_chalk25.default.red(`
|
|
33199
33686
|
\u2717 ${error51.message}
|
|
33200
33687
|
`));
|
|
33201
33688
|
}
|
|
@@ -33207,7 +33694,7 @@ envVars.command("delete <env> <key-or-id>").description("Delete a variable by ke
|
|
|
33207
33694
|
await envVarsDeleteCommand(env, keyOrId, options);
|
|
33208
33695
|
} catch (error51) {
|
|
33209
33696
|
if (error51 instanceof Error) {
|
|
33210
|
-
console.error(
|
|
33697
|
+
console.error(import_chalk25.default.red(`
|
|
33211
33698
|
\u2717 ${error51.message}
|
|
33212
33699
|
`));
|
|
33213
33700
|
}
|
|
@@ -33220,7 +33707,7 @@ envFiles.command("list <env>").description("List files in an environment").actio
|
|
|
33220
33707
|
await envFilesListCommand(env);
|
|
33221
33708
|
} catch (error51) {
|
|
33222
33709
|
if (error51 instanceof Error) {
|
|
33223
|
-
console.error(
|
|
33710
|
+
console.error(import_chalk25.default.red(`
|
|
33224
33711
|
\u2717 ${error51.message}
|
|
33225
33712
|
`));
|
|
33226
33713
|
}
|
|
@@ -33232,7 +33719,7 @@ envFiles.command("set <env> <destination-path>").description("Create or update a
|
|
|
33232
33719
|
await envFilesSetCommand(env, destinationPath, options);
|
|
33233
33720
|
} catch (error51) {
|
|
33234
33721
|
if (error51 instanceof Error) {
|
|
33235
|
-
console.error(
|
|
33722
|
+
console.error(import_chalk25.default.red(`
|
|
33236
33723
|
\u2717 ${error51.message}
|
|
33237
33724
|
`));
|
|
33238
33725
|
}
|
|
@@ -33244,7 +33731,7 @@ envFiles.command("delete <env> <path-or-id>").description("Delete a file by dest
|
|
|
33244
33731
|
await envFilesDeleteCommand(env, pathOrId, options);
|
|
33245
33732
|
} catch (error51) {
|
|
33246
33733
|
if (error51 instanceof Error) {
|
|
33247
|
-
console.error(
|
|
33734
|
+
console.error(import_chalk25.default.red(`
|
|
33248
33735
|
\u2717 ${error51.message}
|
|
33249
33736
|
`));
|
|
33250
33737
|
}
|
|
@@ -33257,7 +33744,7 @@ function registerEnvironmentHookCommands(parent, config3) {
|
|
|
33257
33744
|
try {
|
|
33258
33745
|
await command();
|
|
33259
33746
|
} catch (error51) {
|
|
33260
|
-
if (error51 instanceof Error) console.error(
|
|
33747
|
+
if (error51 instanceof Error) console.error(import_chalk25.default.red(`
|
|
33261
33748
|
\u2717 ${error51.message}
|
|
33262
33749
|
`));
|
|
33263
33750
|
process.exit(1);
|
|
@@ -33293,7 +33780,7 @@ environment.action(async () => {
|
|
|
33293
33780
|
await environmentListCommand();
|
|
33294
33781
|
} catch (error51) {
|
|
33295
33782
|
if (error51 instanceof Error) {
|
|
33296
|
-
console.error(
|
|
33783
|
+
console.error(import_chalk25.default.red(`
|
|
33297
33784
|
\u2717 ${error51.message}
|
|
33298
33785
|
`));
|
|
33299
33786
|
}
|
|
@@ -33344,7 +33831,7 @@ if (isAgentMode()) {
|
|
|
33344
33831
|
await previewAddCommand(workspaceId, options);
|
|
33345
33832
|
} catch (error51) {
|
|
33346
33833
|
if (error51 instanceof Error) {
|
|
33347
|
-
console.error(
|
|
33834
|
+
console.error(import_chalk25.default.red(`
|
|
33348
33835
|
\u2717 ${error51.message}
|
|
33349
33836
|
`));
|
|
33350
33837
|
}
|
|
@@ -33356,7 +33843,7 @@ if (isAgentMode()) {
|
|
|
33356
33843
|
await previewListCommand(workspaceId);
|
|
33357
33844
|
} catch (error51) {
|
|
33358
33845
|
if (error51 instanceof Error) {
|
|
33359
|
-
console.error(
|
|
33846
|
+
console.error(import_chalk25.default.red(`
|
|
33360
33847
|
\u2717 ${error51.message}
|
|
33361
33848
|
`));
|
|
33362
33849
|
}
|
|
@@ -33368,7 +33855,7 @@ if (isAgentMode()) {
|
|
|
33368
33855
|
await previewRemoveCommand(workspaceId, options);
|
|
33369
33856
|
} catch (error51) {
|
|
33370
33857
|
if (error51 instanceof Error) {
|
|
33371
|
-
console.error(
|
|
33858
|
+
console.error(import_chalk25.default.red(`
|
|
33372
33859
|
\u2717 ${error51.message}
|
|
33373
33860
|
`));
|
|
33374
33861
|
}
|
|
@@ -33376,6 +33863,26 @@ if (isAgentMode()) {
|
|
|
33376
33863
|
}
|
|
33377
33864
|
});
|
|
33378
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
|
+
}
|
|
33379
33886
|
if (isAgentMode()) {
|
|
33380
33887
|
const identity = program.command("identity").description("Obtain short-lived workspace identity tokens (OIDC) for the services this workspace calls");
|
|
33381
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);
|
|
@@ -33433,7 +33940,7 @@ if (isAgentMode()) {
|
|
|
33433
33940
|
await mediaUploadCommand(files, options);
|
|
33434
33941
|
} catch (error51) {
|
|
33435
33942
|
if (error51 instanceof Error) {
|
|
33436
|
-
console.error(
|
|
33943
|
+
console.error(import_chalk25.default.red(`
|
|
33437
33944
|
\u2717 ${error51.message}
|
|
33438
33945
|
`));
|
|
33439
33946
|
}
|
|
@@ -33444,7 +33951,7 @@ if (isAgentMode()) {
|
|
|
33444
33951
|
try {
|
|
33445
33952
|
await mediaShareCommand(mediaId);
|
|
33446
33953
|
} catch (error51) {
|
|
33447
|
-
if (error51 instanceof Error) console.error(
|
|
33954
|
+
if (error51 instanceof Error) console.error(import_chalk25.default.red(`
|
|
33448
33955
|
\u2717 ${error51.message}
|
|
33449
33956
|
`));
|
|
33450
33957
|
process.exit(1);
|
|
@@ -33454,7 +33961,7 @@ if (isAgentMode()) {
|
|
|
33454
33961
|
try {
|
|
33455
33962
|
await mediaRevokeCommand(mediaId);
|
|
33456
33963
|
} catch (error51) {
|
|
33457
|
-
if (error51 instanceof Error) console.error(
|
|
33964
|
+
if (error51 instanceof Error) console.error(import_chalk25.default.red(`
|
|
33458
33965
|
\u2717 ${error51.message}
|
|
33459
33966
|
`));
|
|
33460
33967
|
process.exit(1);
|
|
@@ -33464,7 +33971,7 @@ if (isAgentMode()) {
|
|
|
33464
33971
|
try {
|
|
33465
33972
|
await mediaDeleteCommand(mediaId);
|
|
33466
33973
|
} catch (error51) {
|
|
33467
|
-
if (error51 instanceof Error) console.error(
|
|
33974
|
+
if (error51 instanceof Error) console.error(import_chalk25.default.red(`
|
|
33468
33975
|
\u2717 ${error51.message}
|
|
33469
33976
|
`));
|
|
33470
33977
|
process.exit(1);
|
|
@@ -33475,7 +33982,7 @@ if (isAgentMode()) {
|
|
|
33475
33982
|
await mediaListCommand(options);
|
|
33476
33983
|
} catch (error51) {
|
|
33477
33984
|
if (error51 instanceof Error) {
|
|
33478
|
-
console.error(
|
|
33985
|
+
console.error(import_chalk25.default.red(`
|
|
33479
33986
|
\u2717 ${error51.message}
|
|
33480
33987
|
`));
|
|
33481
33988
|
}
|
|
@@ -33488,7 +33995,7 @@ if (isAgentMode()) {
|
|
|
33488
33995
|
await mothershipMonitorChannelCommand(options);
|
|
33489
33996
|
} catch (error51) {
|
|
33490
33997
|
if (error51 instanceof Error) {
|
|
33491
|
-
console.error(
|
|
33998
|
+
console.error(import_chalk25.default.red(`
|
|
33492
33999
|
\u2717 ${error51.message}
|
|
33493
34000
|
`));
|
|
33494
34001
|
}
|
|
@@ -33500,7 +34007,7 @@ if (isAgentMode()) {
|
|
|
33500
34007
|
await mothershipSpawnCommand(options);
|
|
33501
34008
|
} catch (error51) {
|
|
33502
34009
|
if (error51 instanceof Error) {
|
|
33503
|
-
console.error(
|
|
34010
|
+
console.error(import_chalk25.default.red(`
|
|
33504
34011
|
\u2717 ${error51.message}
|
|
33505
34012
|
`));
|
|
33506
34013
|
}
|
|
@@ -33512,7 +34019,7 @@ if (isAgentMode()) {
|
|
|
33512
34019
|
await mothershipRelayCommand(options);
|
|
33513
34020
|
} catch (error51) {
|
|
33514
34021
|
if (error51 instanceof Error) {
|
|
33515
|
-
console.error(
|
|
34022
|
+
console.error(import_chalk25.default.red(`
|
|
33516
34023
|
\u2717 ${error51.message}
|
|
33517
34024
|
`));
|
|
33518
34025
|
}
|
|
@@ -33534,6 +34041,7 @@ if (isAgentMode()) {
|
|
|
33534
34041
|
"automation",
|
|
33535
34042
|
"repos",
|
|
33536
34043
|
"environment",
|
|
34044
|
+
"environment-setup",
|
|
33537
34045
|
"mothership"
|
|
33538
34046
|
]);
|
|
33539
34047
|
const kept = program.commands.filter((cmd) => allowed.has(cmd.name()));
|
|
@@ -33545,7 +34053,7 @@ async function main() {
|
|
|
33545
34053
|
if (process.argv[2] === "computer" && isAgentMode()) {
|
|
33546
34054
|
const result = (0, import_node_child_process3.spawnSync)("replicas-computer", process.argv.slice(3), { stdio: "inherit" });
|
|
33547
34055
|
if (result.error) {
|
|
33548
|
-
console.error(
|
|
34056
|
+
console.error(import_chalk25.default.red(`
|
|
33549
34057
|
\u2717 replicas-computer is unavailable in this workspace image
|
|
33550
34058
|
`));
|
|
33551
34059
|
process.exitCode = 1;
|