lalph 0.3.47 → 0.3.48
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/cli.mjs +223 -77
- package/package.json +2 -2
- package/src/Agents/worker.ts +2 -8
- package/src/Clanka.ts +20 -13
- package/src/PromptGen.ts +5 -6
- package/src/TaskTools.ts +34 -33
- package/src/commands/plan/tasks.ts +2 -0
- package/src/commands/plan.ts +2 -0
- package/src/commands/root.ts +10 -1
package/dist/cli.mjs
CHANGED
|
@@ -24452,6 +24452,50 @@ const publish = /* @__PURE__ */ dual(2, (self, value) => suspend$3(() => {
|
|
|
24452
24452
|
return self.strategy.handleSurplus(self.pubsub, self.subscribers, [value], self.shutdownFlag);
|
|
24453
24453
|
}));
|
|
24454
24454
|
/**
|
|
24455
|
+
* Publishes all of the specified messages to the `PubSub`, returning whether they
|
|
24456
|
+
* were published to the `PubSub`.
|
|
24457
|
+
*
|
|
24458
|
+
* @example
|
|
24459
|
+
* ```ts
|
|
24460
|
+
* import { Effect } from "effect"
|
|
24461
|
+
* import * as PubSub from "effect/PubSub"
|
|
24462
|
+
*
|
|
24463
|
+
* const program = Effect.gen(function*() {
|
|
24464
|
+
* const pubsub = yield* PubSub.bounded<string>(10)
|
|
24465
|
+
*
|
|
24466
|
+
* // Publish multiple messages at once
|
|
24467
|
+
* const messages = ["Hello", "World", "from", "Effect"]
|
|
24468
|
+
* const allPublished = yield* PubSub.publishAll(pubsub, messages)
|
|
24469
|
+
* console.log("All messages published:", allPublished) // true
|
|
24470
|
+
*
|
|
24471
|
+
* // With a smaller capacity
|
|
24472
|
+
* const smallPubsub = yield* PubSub.bounded<string>(2)
|
|
24473
|
+
* const manyMessages = ["msg1", "msg2", "msg3", "msg4"]
|
|
24474
|
+
*
|
|
24475
|
+
* // Will suspend until space becomes available for all messages
|
|
24476
|
+
* const publishAllEffect = PubSub.publishAll(smallPubsub, manyMessages)
|
|
24477
|
+
*
|
|
24478
|
+
* // Subscribe to consume messages and free space
|
|
24479
|
+
* yield* Effect.scoped(Effect.gen(function*() {
|
|
24480
|
+
* const subscription = yield* PubSub.subscribe(smallPubsub)
|
|
24481
|
+
* yield* PubSub.takeAll(subscription) // consume all messages
|
|
24482
|
+
* const result = yield* publishAllEffect
|
|
24483
|
+
* console.log("All messages eventually published:", result)
|
|
24484
|
+
* }))
|
|
24485
|
+
* })
|
|
24486
|
+
* ```
|
|
24487
|
+
*
|
|
24488
|
+
* @since 2.0.0
|
|
24489
|
+
* @category publishing
|
|
24490
|
+
*/
|
|
24491
|
+
const publishAll = /* @__PURE__ */ dual(2, (self, elements) => suspend$3(() => {
|
|
24492
|
+
if (self.shutdownFlag.current) return interrupt$1;
|
|
24493
|
+
const surplus = self.pubsub.publishAll(elements);
|
|
24494
|
+
self.strategy.completeSubscribersUnsafe(self.pubsub, self.subscribers);
|
|
24495
|
+
if (surplus.length === 0) return succeed$3(true);
|
|
24496
|
+
return self.strategy.handleSurplus(self.pubsub, self.subscribers, surplus, self.shutdownFlag);
|
|
24497
|
+
}));
|
|
24498
|
+
/**
|
|
24455
24499
|
* Subscribes to receive messages from the `PubSub`. The resulting subscription can
|
|
24456
24500
|
* be evaluated multiple times within the scope to take a message from the `PubSub`
|
|
24457
24501
|
* each time.
|
|
@@ -28443,6 +28487,11 @@ const toPull$1 = /* @__PURE__ */ fnUntraced(function* (self) {
|
|
|
28443
28487
|
const toPullScoped = (self, scope) => toTransform(self)(done(), scope);
|
|
28444
28488
|
const makePubSub = (options) => acquireRelease(options.capacity === "unbounded" ? unbounded$1(options) : options.strategy === "dropping" ? dropping(options) : options.strategy === "sliding" ? sliding(options) : bounded$1(options), shutdown$1);
|
|
28445
28489
|
/**
|
|
28490
|
+
* @since 4.0.0
|
|
28491
|
+
* @category Destructors
|
|
28492
|
+
*/
|
|
28493
|
+
const runIntoPubSubArray = /* @__PURE__ */ dual((args) => isChannel(args[0]), (self, pubsub, options) => runForEach$1(self, (value) => publishAll(pubsub, value)).pipe(options?.shutdownOnEnd === true ? ensuring$2(shutdown$1(pubsub)) : identity));
|
|
28494
|
+
/**
|
|
28446
28495
|
* Converts a channel to a PubSub for concurrent consumption.
|
|
28447
28496
|
*
|
|
28448
28497
|
* @since 4.0.0
|
|
@@ -28913,9 +28962,9 @@ const getState = (self) => uninterruptibleMask((restore) => {
|
|
|
28913
28962
|
const get$11 = /* @__PURE__ */ fnUntraced(function* (self_) {
|
|
28914
28963
|
const self = self_;
|
|
28915
28964
|
const state = yield* getState(self);
|
|
28916
|
-
const scope$
|
|
28965
|
+
const scope$8 = yield* scope;
|
|
28917
28966
|
const isFinite = self.idleTimeToLive !== void 0 && isFinite$2(self.idleTimeToLive);
|
|
28918
|
-
yield* addFinalizerExit(scope$
|
|
28967
|
+
yield* addFinalizerExit(scope$8, () => {
|
|
28919
28968
|
state.refCount--;
|
|
28920
28969
|
if (state.refCount > 0) return void_$1;
|
|
28921
28970
|
if (self.idleTimeToLive === void 0) {
|
|
@@ -30930,6 +30979,38 @@ const toReadableStreamWith = /* @__PURE__ */ dual((args) => isStream(args[0]), (
|
|
|
30930
30979
|
*/
|
|
30931
30980
|
const toReadableStreamEffect = /* @__PURE__ */ dual((args) => isStream(args[0]), (self, options) => map$8(services(), (context) => toReadableStreamWith(self, context, options)));
|
|
30932
30981
|
/**
|
|
30982
|
+
* Runs the stream, publishing elements into the provided PubSub.
|
|
30983
|
+
*
|
|
30984
|
+
* `shutdownOnEnd` controls whether the PubSub is shut down when the stream ends.
|
|
30985
|
+
* It only shuts down when set to `true`.
|
|
30986
|
+
*
|
|
30987
|
+
* @example
|
|
30988
|
+
* ```ts
|
|
30989
|
+
* import { Console, Effect, PubSub, Stream } from "effect"
|
|
30990
|
+
*
|
|
30991
|
+
* const program = Effect.scoped(Effect.gen(function* () {
|
|
30992
|
+
* const pubsub = yield* PubSub.unbounded<number>()
|
|
30993
|
+
* const subscription = yield* PubSub.subscribe(pubsub)
|
|
30994
|
+
*
|
|
30995
|
+
* yield* Stream.runIntoPubSub(Stream.fromIterable([1, 2]), pubsub)
|
|
30996
|
+
*
|
|
30997
|
+
* const first = yield* PubSub.take(subscription)
|
|
30998
|
+
* const second = yield* PubSub.take(subscription)
|
|
30999
|
+
*
|
|
31000
|
+
* yield* Console.log(first)
|
|
31001
|
+
* yield* Console.log(second)
|
|
31002
|
+
* }))
|
|
31003
|
+
*
|
|
31004
|
+
* Effect.runPromise(program)
|
|
31005
|
+
* //=> 1
|
|
31006
|
+
* //=> 2
|
|
31007
|
+
* ```
|
|
31008
|
+
*
|
|
31009
|
+
* @since 2.0.0
|
|
31010
|
+
* @category Destructors
|
|
31011
|
+
*/
|
|
31012
|
+
const runIntoPubSub = /* @__PURE__ */ dual((args) => isStream(args[0]), (self, pubsub, options) => runIntoPubSubArray(self.channel, pubsub, options));
|
|
31013
|
+
/**
|
|
30933
31014
|
* Converts a stream to a PubSub for concurrent consumption.
|
|
30934
31015
|
*
|
|
30935
31016
|
* `Take` values include the stream's end and failure signals.
|
|
@@ -52972,6 +53053,32 @@ const randomWith = (f) => withFiber((fiber) => succeed$3(f(fiber.getRef(Random))
|
|
|
52972
53053
|
* @category Random Number Generators
|
|
52973
53054
|
*/
|
|
52974
53055
|
const next = /* @__PURE__ */ randomWith((r) => r.nextDoubleUnsafe());
|
|
53056
|
+
/**
|
|
53057
|
+
* Uses the pseudo-random number generator to shuffle the specified iterable.
|
|
53058
|
+
*
|
|
53059
|
+
* @example
|
|
53060
|
+
* ```ts
|
|
53061
|
+
* import { Effect, Random } from "effect"
|
|
53062
|
+
*
|
|
53063
|
+
* const program = Effect.gen(function*() {
|
|
53064
|
+
* const values = yield* Random.shuffle([1, 2, 3, 4, 5])
|
|
53065
|
+
* console.log(values)
|
|
53066
|
+
* })
|
|
53067
|
+
* ```
|
|
53068
|
+
*
|
|
53069
|
+
* @since 4.0.0
|
|
53070
|
+
* @category Random Number Generators
|
|
53071
|
+
*/
|
|
53072
|
+
const shuffle = (elements) => randomWith((r) => {
|
|
53073
|
+
const buffer = Array.from(elements);
|
|
53074
|
+
for (let i = buffer.length - 1; i >= 1; i = i - 1) {
|
|
53075
|
+
const index = Math.min(i, Math.floor(r.nextDoubleUnsafe() * (i + 1)));
|
|
53076
|
+
const value = buffer[i];
|
|
53077
|
+
buffer[i] = buffer[index];
|
|
53078
|
+
buffer[index] = value;
|
|
53079
|
+
}
|
|
53080
|
+
return buffer;
|
|
53081
|
+
});
|
|
52975
53082
|
//#endregion
|
|
52976
53083
|
//#region node_modules/.pnpm/effect@4.0.0-beta.30/node_modules/effect/dist/Ref.js
|
|
52977
53084
|
const RefProto = {
|
|
@@ -53380,7 +53487,7 @@ var BackingPersistence = class extends Service$1()("effect/persistence/BackingPe
|
|
|
53380
53487
|
*/
|
|
53381
53488
|
const layer$21 = /* @__PURE__ */ effect$1(Persistence)(/* @__PURE__ */ gen(function* () {
|
|
53382
53489
|
const backing = yield* BackingPersistence;
|
|
53383
|
-
const scope$
|
|
53490
|
+
const scope$6 = yield* scope;
|
|
53384
53491
|
return Persistence.of({ make: fnUntraced(function* (options) {
|
|
53385
53492
|
const storage = yield* backing.make(options.storeId);
|
|
53386
53493
|
const timeToLive = options.timeToLive ?? (() => infinity);
|
|
@@ -53415,7 +53522,7 @@ const layer$21 = /* @__PURE__ */ effect$1(Persistence)(/* @__PURE__ */ gen(funct
|
|
|
53415
53522
|
}
|
|
53416
53523
|
out[i] = exit$3.value;
|
|
53417
53524
|
}
|
|
53418
|
-
if (toRemove) for (let i = 0; i < toRemove.length; i++) yield* forkIn(storage.remove(toRemove[i]), scope$
|
|
53525
|
+
if (toRemove) for (let i = 0; i < toRemove.length; i++) yield* forkIn(storage.remove(toRemove[i]), scope$6);
|
|
53419
53526
|
return out;
|
|
53420
53527
|
}),
|
|
53421
53528
|
set(key, value) {
|
|
@@ -85497,9 +85604,9 @@ const layer$6 = /* @__PURE__ */ provideMerge(layer$20, /* @__PURE__ */ mergeAll$
|
|
|
85497
85604
|
* @category constructors
|
|
85498
85605
|
*/
|
|
85499
85606
|
const make$15 = /* @__PURE__ */ fnUntraced(function* (evaluate, options) {
|
|
85500
|
-
const scope$
|
|
85607
|
+
const scope$4 = yield* scope;
|
|
85501
85608
|
const server = evaluate();
|
|
85502
|
-
yield* addFinalizer$1(scope$
|
|
85609
|
+
yield* addFinalizer$1(scope$4, callback$1((resume) => {
|
|
85503
85610
|
if (!server.listening) return resume(void_$1);
|
|
85504
85611
|
server.close((error) => {
|
|
85505
85612
|
if (error) resume(die$2(error));
|
|
@@ -85519,7 +85626,7 @@ const make$15 = /* @__PURE__ */ fnUntraced(function* (evaluate, options) {
|
|
|
85519
85626
|
const address = server.address();
|
|
85520
85627
|
const wss = yield* acquireRelease(sync(() => new import_websocket_server.default({ noServer: true })), (wss) => callback$1((resume) => {
|
|
85521
85628
|
wss.close(() => resume(void_$1));
|
|
85522
|
-
})).pipe(provide$4(scope$
|
|
85629
|
+
})).pipe(provide$4(scope$4), cached);
|
|
85523
85630
|
return make$21({
|
|
85524
85631
|
address: typeof address === "string" ? {
|
|
85525
85632
|
_tag: "UnixAddress",
|
|
@@ -85530,14 +85637,14 @@ const make$15 = /* @__PURE__ */ fnUntraced(function* (evaluate, options) {
|
|
|
85530
85637
|
port: address.port
|
|
85531
85638
|
},
|
|
85532
85639
|
serve: fnUntraced(function* (httpApp, middleware) {
|
|
85533
|
-
const scope$
|
|
85640
|
+
const scope$5 = yield* scope;
|
|
85534
85641
|
const handler = yield* makeHandler(httpApp, {
|
|
85535
85642
|
middleware,
|
|
85536
|
-
scope: scope$
|
|
85643
|
+
scope: scope$5
|
|
85537
85644
|
});
|
|
85538
85645
|
const upgradeHandler = yield* makeUpgradeHandler(wss, httpApp, {
|
|
85539
85646
|
middleware,
|
|
85540
|
-
scope: scope$
|
|
85647
|
+
scope: scope$5
|
|
85541
85648
|
});
|
|
85542
85649
|
yield* addFinalizer(() => sync(() => {
|
|
85543
85650
|
server.off("request", handler);
|
|
@@ -86389,12 +86496,12 @@ const AtomRegistry = /* @__PURE__ */ Service$1(TypeId$6);
|
|
|
86389
86496
|
* @category Layers
|
|
86390
86497
|
*/
|
|
86391
86498
|
const layerOptions = (options) => effect$1(AtomRegistry, gen(function* () {
|
|
86392
|
-
const scope$
|
|
86499
|
+
const scope$3 = yield* scope;
|
|
86393
86500
|
const registry = make$13({
|
|
86394
86501
|
...options,
|
|
86395
86502
|
scheduleTask: options?.scheduleTask
|
|
86396
86503
|
});
|
|
86397
|
-
yield* addFinalizer$1(scope$
|
|
86504
|
+
yield* addFinalizer$1(scope$3, sync(() => registry.dispose()));
|
|
86398
86505
|
return registry;
|
|
86399
86506
|
}));
|
|
86400
86507
|
/**
|
|
@@ -180286,12 +180393,11 @@ The following instructions should be done without interaction or asking for perm
|
|
|
180286
180393
|
Set \`githubPrNumber\` to the PR number if one exists, otherwise use \`null\`.
|
|
180287
180394
|
` : "\n\nLeave `githubPrNumber` as null."}
|
|
180288
180395
|
`;
|
|
180289
|
-
const promptChooseClanka = (options) =>
|
|
180290
|
-
**
|
|
180291
|
-
|
|
180292
|
-
|
|
180293
|
-
|
|
180294
|
-
- Decide which single task to work on next from "listEligibleTasks". This should
|
|
180396
|
+
const promptChooseClanka = (options) => `- Use the "listEligibleTasks" function to view the list of tasks that you can start working on.
|
|
180397
|
+
- **NO NOT PARSE THE yaml OUTPUT IN ANY WAY**
|
|
180398
|
+
- **DO NOT** implement the task yet.
|
|
180399
|
+
- **DO NOT** use the "delegate" function for any step in this workflow
|
|
180400
|
+
- After reading through the list of tasks, choose the task to work on. This should
|
|
180295
180401
|
be the task YOU decide as the most important to work on next, not just the
|
|
180296
180402
|
first task in the list.${options.gitFlow.requiresGithubPr ? `
|
|
180297
180403
|
- Check if there is an open Github PR for the chosen task. If there is, note the PR number for inclusion when calling "chooseTask".
|
|
@@ -188245,7 +188351,7 @@ var ji = Bt, Ii = Object.assign(Qe, { sync: Bt }), zi = Ut, Bi = Object.assign(e
|
|
|
188245
188351
|
});
|
|
188246
188352
|
Ze.glob = Ze;
|
|
188247
188353
|
//#endregion
|
|
188248
|
-
//#region node_modules/.pnpm/clanka@0.0.
|
|
188354
|
+
//#region node_modules/.pnpm/clanka@0.0.21_@effect+ai-openai-compat@4.0.0-beta.30_effect@4.0.0-beta.30__@effect+ai-o_c6e3079f8d7bc58ae58eff3c7a31d650/node_modules/clanka/dist/ApplyPatch.js
|
|
188249
188355
|
/**
|
|
188250
188356
|
* @since 1.0.0
|
|
188251
188357
|
*/
|
|
@@ -188574,7 +188680,7 @@ const patchChunks = (file, input, chunks) => {
|
|
|
188574
188680
|
return eol === "\r\n" ? text.replace(/\n/g, "\r\n") : text;
|
|
188575
188681
|
};
|
|
188576
188682
|
//#endregion
|
|
188577
|
-
//#region node_modules/.pnpm/clanka@0.0.
|
|
188683
|
+
//#region node_modules/.pnpm/clanka@0.0.21_@effect+ai-openai-compat@4.0.0-beta.30_effect@4.0.0-beta.30__@effect+ai-o_c6e3079f8d7bc58ae58eff3c7a31d650/node_modules/clanka/dist/AgentTools.js
|
|
188578
188684
|
/**
|
|
188579
188685
|
* @since 1.0.0
|
|
188580
188686
|
*/
|
|
@@ -188870,7 +188976,7 @@ const AgentToolHandlers = AgentTools.toLayer(gen(function* () {
|
|
|
188870
188976
|
}));
|
|
188871
188977
|
var ApplyPatchError = class extends TaggedClass$1("ApplyPatchError") {};
|
|
188872
188978
|
//#endregion
|
|
188873
|
-
//#region node_modules/.pnpm/clanka@0.0.
|
|
188979
|
+
//#region node_modules/.pnpm/clanka@0.0.21_@effect+ai-openai-compat@4.0.0-beta.30_effect@4.0.0-beta.30__@effect+ai-o_c6e3079f8d7bc58ae58eff3c7a31d650/node_modules/clanka/dist/Executor.js
|
|
188874
188980
|
/**
|
|
188875
188981
|
* @since 1.0.0
|
|
188876
188982
|
*/
|
|
@@ -188950,7 +189056,7 @@ var QueueWriteStream = class extends Writable {
|
|
|
188950
189056
|
}
|
|
188951
189057
|
};
|
|
188952
189058
|
//#endregion
|
|
188953
|
-
//#region node_modules/.pnpm/clanka@0.0.
|
|
189059
|
+
//#region node_modules/.pnpm/clanka@0.0.21_@effect+ai-openai-compat@4.0.0-beta.30_effect@4.0.0-beta.30__@effect+ai-o_c6e3079f8d7bc58ae58eff3c7a31d650/node_modules/clanka/dist/TypeBuilder.js
|
|
188954
189060
|
const resolveDocumentation = resolveAt("documentation");
|
|
188955
189061
|
const identifierPattern = /^[$A-Z_a-z][$0-9A-Z_a-z]*$/u;
|
|
188956
189062
|
const Precedence = {
|
|
@@ -189223,7 +189329,7 @@ const render = (schema, options) => {
|
|
|
189223
189329
|
return printNode({ text: documentation === void 0 ? rendered.text : `${renderJsDoc(documentation, 0, printerOptions)}${printerOptions.newLine}${rendered.text}` }, printerOptions);
|
|
189224
189330
|
};
|
|
189225
189331
|
//#endregion
|
|
189226
|
-
//#region node_modules/.pnpm/clanka@0.0.
|
|
189332
|
+
//#region node_modules/.pnpm/clanka@0.0.21_@effect+ai-openai-compat@4.0.0-beta.30_effect@4.0.0-beta.30__@effect+ai-o_c6e3079f8d7bc58ae58eff3c7a31d650/node_modules/clanka/dist/ToolkitRenderer.js
|
|
189227
189333
|
/**
|
|
189228
189334
|
* @since 1.0.0
|
|
189229
189335
|
*/
|
|
@@ -189245,7 +189351,7 @@ declare function ${name}(${params}): Promise<${render(tool.successSchema)}>`);
|
|
|
189245
189351
|
}) });
|
|
189246
189352
|
};
|
|
189247
189353
|
//#endregion
|
|
189248
|
-
//#region node_modules/.pnpm/clanka@0.0.
|
|
189354
|
+
//#region node_modules/.pnpm/clanka@0.0.21_@effect+ai-openai-compat@4.0.0-beta.30_effect@4.0.0-beta.30__@effect+ai-o_c6e3079f8d7bc58ae58eff3c7a31d650/node_modules/clanka/dist/Agent.js
|
|
189249
189355
|
/**
|
|
189250
189356
|
* @since 1.0.0
|
|
189251
189357
|
*/
|
|
@@ -189300,7 +189406,8 @@ ${content}
|
|
|
189300
189406
|
for (const [id, state] of outputBuffer) {
|
|
189301
189407
|
outputBuffer.delete(id);
|
|
189302
189408
|
offerAllUnsafe(output, state);
|
|
189303
|
-
|
|
189409
|
+
const lastPart = state[state.length - 1];
|
|
189410
|
+
if (lastPart._tag === "ScriptDelta" || lastPart._tag === "ReasoningDelta") {
|
|
189304
189411
|
currentOutputAgent = id;
|
|
189305
189412
|
break;
|
|
189306
189413
|
}
|
|
@@ -189555,7 +189662,7 @@ Javascript output:
|
|
|
189555
189662
|
\`\`\``;
|
|
189556
189663
|
};
|
|
189557
189664
|
const generateSystemMulti = (toolsDts) => {
|
|
189558
|
-
return `
|
|
189665
|
+
return `You complete your tasks by **only writing javascript code** to interact with your environment.
|
|
189559
189666
|
|
|
189560
189667
|
- Use \`console.log\` to print any output you need.
|
|
189561
189668
|
- Top level await is supported.
|
|
@@ -200013,7 +200120,7 @@ const transformToolCallParams = /* @__PURE__ */ fnUntraced(function* (tools, too
|
|
|
200013
200120
|
})));
|
|
200014
200121
|
});
|
|
200015
200122
|
//#endregion
|
|
200016
|
-
//#region node_modules/.pnpm/clanka@0.0.
|
|
200123
|
+
//#region node_modules/.pnpm/clanka@0.0.21_@effect+ai-openai-compat@4.0.0-beta.30_effect@4.0.0-beta.30__@effect+ai-o_c6e3079f8d7bc58ae58eff3c7a31d650/node_modules/clanka/dist/CodexAuth.js
|
|
200017
200124
|
/**
|
|
200018
200125
|
* @since 1.0.0
|
|
200019
200126
|
*/
|
|
@@ -200233,7 +200340,7 @@ var CodexAuth = class CodexAuth extends Service$1()("clanka/CodexAuth") {
|
|
|
200233
200340
|
static layerClient = this.layerClientNoDeps.pipe(provide$3(CodexAuth.layer));
|
|
200234
200341
|
};
|
|
200235
200342
|
//#endregion
|
|
200236
|
-
//#region node_modules/.pnpm/clanka@0.0.
|
|
200343
|
+
//#region node_modules/.pnpm/clanka@0.0.21_@effect+ai-openai-compat@4.0.0-beta.30_effect@4.0.0-beta.30__@effect+ai-o_c6e3079f8d7bc58ae58eff3c7a31d650/node_modules/clanka/dist/Codex.js
|
|
200237
200344
|
/**
|
|
200238
200345
|
* @since 1.0.0
|
|
200239
200346
|
*/
|
|
@@ -201548,7 +201655,7 @@ const getUsageDetailNumber = (details, field) => {
|
|
|
201548
201655
|
return typeof value === "number" ? value : void 0;
|
|
201549
201656
|
};
|
|
201550
201657
|
//#endregion
|
|
201551
|
-
//#region node_modules/.pnpm/clanka@0.0.
|
|
201658
|
+
//#region node_modules/.pnpm/clanka@0.0.21_@effect+ai-openai-compat@4.0.0-beta.30_effect@4.0.0-beta.30__@effect+ai-o_c6e3079f8d7bc58ae58eff3c7a31d650/node_modules/clanka/dist/CopilotAuth.js
|
|
201552
201659
|
/**
|
|
201553
201660
|
* @since 1.0.0
|
|
201554
201661
|
*/
|
|
@@ -201739,7 +201846,7 @@ var GithubCopilotAuth = class GithubCopilotAuth extends Service$1()("clanka/Gith
|
|
|
201739
201846
|
static layerClient = this.layerClientNoDeps.pipe(provide$3(GithubCopilotAuth.layer));
|
|
201740
201847
|
};
|
|
201741
201848
|
//#endregion
|
|
201742
|
-
//#region node_modules/.pnpm/clanka@0.0.
|
|
201849
|
+
//#region node_modules/.pnpm/clanka@0.0.21_@effect+ai-openai-compat@4.0.0-beta.30_effect@4.0.0-beta.30__@effect+ai-o_c6e3079f8d7bc58ae58eff3c7a31d650/node_modules/clanka/dist/Copilot.js
|
|
201743
201850
|
/**
|
|
201744
201851
|
* @since 1.0.0
|
|
201745
201852
|
*/
|
|
@@ -202162,7 +202269,7 @@ Object.defineProperties(createChalk.prototype, styles);
|
|
|
202162
202269
|
const chalk = createChalk();
|
|
202163
202270
|
createChalk({ level: stderrColor ? stderrColor.level : 0 });
|
|
202164
202271
|
//#endregion
|
|
202165
|
-
//#region node_modules/.pnpm/clanka@0.0.
|
|
202272
|
+
//#region node_modules/.pnpm/clanka@0.0.21_@effect+ai-openai-compat@4.0.0-beta.30_effect@4.0.0-beta.30__@effect+ai-o_c6e3079f8d7bc58ae58eff3c7a31d650/node_modules/clanka/dist/OutputFormatter.js
|
|
202166
202273
|
/**
|
|
202167
202274
|
* @since 1.0.0
|
|
202168
202275
|
*/
|
|
@@ -202203,6 +202310,47 @@ const scriptIcon = "";
|
|
|
202203
202310
|
const subagentIcon = " ";
|
|
202204
202311
|
const thinkingIcon = "";
|
|
202205
202312
|
const doneIcon = "";
|
|
202313
|
+
/**
|
|
202314
|
+
* @since 1.0.0
|
|
202315
|
+
* @category Muxer
|
|
202316
|
+
*/
|
|
202317
|
+
var Muxer = class extends Service$1()("clanka/OutputFormatter/Muxer") {};
|
|
202318
|
+
/**
|
|
202319
|
+
* @since 1.0.0
|
|
202320
|
+
* @category Muxer
|
|
202321
|
+
*/
|
|
202322
|
+
const layerMuxer = (formatter) => effect$1(Muxer, gen(function* () {
|
|
202323
|
+
const scope$2 = yield* scope;
|
|
202324
|
+
const output = yield* unbounded$1();
|
|
202325
|
+
let agentCount = 0;
|
|
202326
|
+
let currentAgentId = null;
|
|
202327
|
+
const semaphore = makeUnsafe$8(1);
|
|
202328
|
+
return Muxer.of({
|
|
202329
|
+
add(stream) {
|
|
202330
|
+
const id = ++agentCount;
|
|
202331
|
+
return stream.pipe(tap(fnUntraced(function* (part_) {
|
|
202332
|
+
if (currentAgentId === null || id !== currentAgentId) yield* semaphore.take(1);
|
|
202333
|
+
switch ((part_._tag === "SubagentPart" ? part_.part : part_)._tag) {
|
|
202334
|
+
case "ReasoningStart":
|
|
202335
|
+
case "ScriptStart":
|
|
202336
|
+
currentAgentId = id;
|
|
202337
|
+
break;
|
|
202338
|
+
case "ScriptDelta":
|
|
202339
|
+
case "ReasoningDelta": break;
|
|
202340
|
+
default:
|
|
202341
|
+
currentAgentId = null;
|
|
202342
|
+
break;
|
|
202343
|
+
}
|
|
202344
|
+
if (id !== currentAgentId) yield* semaphore.release(1);
|
|
202345
|
+
})), formatter, runIntoPubSub(output), onExit$1(() => {
|
|
202346
|
+
if (currentAgentId !== id) return void_$1;
|
|
202347
|
+
currentAgentId = null;
|
|
202348
|
+
return semaphore.release(1);
|
|
202349
|
+
}), forkIn(scope$2), asVoid);
|
|
202350
|
+
},
|
|
202351
|
+
output: fromPubSub(output)
|
|
202352
|
+
});
|
|
202353
|
+
}));
|
|
202206
202354
|
//#endregion
|
|
202207
202355
|
//#region src/TaskTools.ts
|
|
202208
202356
|
var ChosenTaskDeferred = class extends Reference("lalph/TaskTools/ChosenTaskDeferred", { defaultValue: makeUnsafe$13 }) {};
|
|
@@ -202221,6 +202369,14 @@ const TaskList = Array$1(Struct({
|
|
|
202221
202369
|
"blockedBy"
|
|
202222
202370
|
])
|
|
202223
202371
|
}));
|
|
202372
|
+
const toTaskListItem = (issue) => ({
|
|
202373
|
+
id: issue.id ?? "",
|
|
202374
|
+
title: issue.title,
|
|
202375
|
+
description: issue.description,
|
|
202376
|
+
state: issue.state,
|
|
202377
|
+
priority: issue.priority,
|
|
202378
|
+
blockedBy: issue.blockedBy
|
|
202379
|
+
});
|
|
202224
202380
|
var TaskTools = class extends make$9(make$7("listTasks", {
|
|
202225
202381
|
description: "Returns the current list of tasks.",
|
|
202226
202382
|
success: TaskList,
|
|
@@ -202251,43 +202407,31 @@ var TaskTools = class extends make$9(make$7("listTasks", {
|
|
|
202251
202407
|
parameters: String$1.annotate({ identifier: "taskId" }),
|
|
202252
202408
|
dependencies: [CurrentProjectId]
|
|
202253
202409
|
})) {};
|
|
202254
|
-
var
|
|
202410
|
+
var TaskChooseTools = class extends make$9(make$7("chooseTask", {
|
|
202255
202411
|
description: "Choose the task to work on",
|
|
202256
202412
|
parameters: Struct({
|
|
202257
202413
|
taskId: String$1,
|
|
202258
202414
|
githubPrNumber: optional$2(Number$1)
|
|
202259
202415
|
})
|
|
202260
202416
|
}), make$7("listEligibleTasks", {
|
|
202261
|
-
description: "List tasks eligible for being chosen with chooseTask.",
|
|
202262
|
-
success:
|
|
202417
|
+
description: "List tasks eligible for being chosen with chooseTask in yaml format.",
|
|
202418
|
+
success: String$1,
|
|
202263
202419
|
dependencies: [CurrentProjectId]
|
|
202264
|
-
}))
|
|
202420
|
+
})) {};
|
|
202421
|
+
var TaskToolsWithChoose = class extends merge(TaskTools, TaskChooseTools) {};
|
|
202265
202422
|
const TaskToolsHandlers = TaskToolsWithChoose.toLayer(gen(function* () {
|
|
202266
202423
|
const source = yield* IssueSource;
|
|
202267
202424
|
return TaskToolsWithChoose.of({
|
|
202268
202425
|
listTasks: fn("TaskTools.listTasks")(function* () {
|
|
202269
202426
|
yield* log$1(`Calling "listTasks"`);
|
|
202270
202427
|
const projectId = yield* CurrentProjectId;
|
|
202271
|
-
return (yield* source.issues(projectId)).map(
|
|
202272
|
-
id: issue.id ?? "",
|
|
202273
|
-
title: issue.title,
|
|
202274
|
-
description: issue.description,
|
|
202275
|
-
state: issue.state,
|
|
202276
|
-
priority: issue.priority,
|
|
202277
|
-
blockedBy: issue.blockedBy
|
|
202278
|
-
}));
|
|
202428
|
+
return (yield* source.issues(projectId)).map(toTaskListItem);
|
|
202279
202429
|
}, orDie$2),
|
|
202280
202430
|
listEligibleTasks: fn("TaskTools.listEligibleTasks")(function* () {
|
|
202281
202431
|
yield* log$1(`Calling "listEligibleTasks"`);
|
|
202282
202432
|
const projectId = yield* CurrentProjectId;
|
|
202283
|
-
|
|
202284
|
-
|
|
202285
|
-
title: issue.title,
|
|
202286
|
-
description: issue.description,
|
|
202287
|
-
state: issue.state,
|
|
202288
|
-
priority: issue.priority,
|
|
202289
|
-
blockedBy: issue.blockedBy
|
|
202290
|
-
}));
|
|
202433
|
+
const shuffled = yield* shuffle((yield* source.issues(projectId)).filter((t) => t.state === "todo" && t.blockedBy.length === 0).map(toTaskListItem));
|
|
202434
|
+
return import_dist.stringify(shuffled, null, 2);
|
|
202291
202435
|
}, orDie$2),
|
|
202292
202436
|
chooseTask: fn("TaskTools.chooseTask")(function* (options) {
|
|
202293
202437
|
yield* log$1(`Calling "chooseTask"`).pipe(annotateLogs(options));
|
|
@@ -202359,28 +202503,27 @@ const reasoningToCopilotConfig = (model, reasoning) => {
|
|
|
202359
202503
|
};
|
|
202360
202504
|
//#endregion
|
|
202361
202505
|
//#region src/Clanka.ts
|
|
202362
|
-
const
|
|
202363
|
-
|
|
202364
|
-
|
|
202365
|
-
|
|
202366
|
-
|
|
202367
|
-
|
|
202368
|
-
|
|
202369
|
-
|
|
202370
|
-
|
|
202371
|
-
|
|
202372
|
-
|
|
202373
|
-
|
|
202374
|
-
|
|
202375
|
-
|
|
202376
|
-
|
|
202377
|
-
|
|
202378
|
-
|
|
202379
|
-
|
|
202380
|
-
},
|
|
202381
|
-
|
|
202382
|
-
|
|
202383
|
-
);
|
|
202506
|
+
const ClankaMuxerLayer = effectDiscard(gen(function* () {
|
|
202507
|
+
const muxer = yield* Muxer;
|
|
202508
|
+
const stdio = yield* Stdio;
|
|
202509
|
+
yield* muxer.output.pipe(run$7(stdio.stdout()), forkScoped);
|
|
202510
|
+
})).pipe(provideMerge(layerMuxer(pretty)));
|
|
202511
|
+
const runClanka = fnUntraced(function* (options) {
|
|
202512
|
+
const models = yield* ClankaModels;
|
|
202513
|
+
const muxer = yield* Muxer;
|
|
202514
|
+
const agent = yield* make$5({
|
|
202515
|
+
...options,
|
|
202516
|
+
tools: options.withChoose ? TaskChooseTools : TaskTools,
|
|
202517
|
+
subagentModel: clankaSubagent(models, options.model)
|
|
202518
|
+
}).pipe(provide$1(models.get(options.model)));
|
|
202519
|
+
yield* muxer.add(agent.output);
|
|
202520
|
+
let stream = options.stallTimeout ? withStallTimeout(options.stallTimeout)(agent.output) : agent.output;
|
|
202521
|
+
if (options.steer) yield* options.steer.pipe(switchMap(fnUntraced(function* (message) {
|
|
202522
|
+
yield* log$1(`Received steer message: ${message}`);
|
|
202523
|
+
yield* agent.steer(message);
|
|
202524
|
+
}, fromEffectDrain)), runDrain, forkScoped);
|
|
202525
|
+
yield* stream.pipe(runDrain, catchTag$1("AgentFinished", () => void_$1));
|
|
202526
|
+
}, scoped$1, provide$1([layerServices, TaskToolsHandlers]));
|
|
202384
202527
|
//#endregion
|
|
202385
202528
|
//#region src/Agents/worker.ts
|
|
202386
202529
|
const agentWorker = fnUntraced(function* (options) {
|
|
@@ -202394,7 +202537,7 @@ const agentWorker = fnUntraced(function* (options) {
|
|
|
202394
202537
|
prompt: options.prompt,
|
|
202395
202538
|
stallTimeout: options.stallTimeout,
|
|
202396
202539
|
steer: options.steer
|
|
202397
|
-
})
|
|
202540
|
+
});
|
|
202398
202541
|
return ExitCode(0);
|
|
202399
202542
|
}
|
|
202400
202543
|
return yield* pipe(options.preset.cliAgent.command({
|
|
@@ -202719,7 +202862,7 @@ const run = fnUntraced(function* (options) {
|
|
|
202719
202862
|
preset: taskPreset,
|
|
202720
202863
|
prompt: instructions,
|
|
202721
202864
|
steer
|
|
202722
|
-
}).pipe(catchStallInReview, withSpan("Main.agentWorker"))}`);
|
|
202865
|
+
}).pipe(provideService$2(CurrentTaskRef, issueRef), catchStallInReview, withSpan("Main.agentWorker"))}`);
|
|
202723
202866
|
if (options.review) {
|
|
202724
202867
|
registry.update(currentWorker.state, (s) => s.transitionTo(WorkerStatus.Reviewing({ issueId: taskId })));
|
|
202725
202868
|
yield* agentReviewer({
|
|
@@ -202821,6 +202964,7 @@ const commandRoot = make$46("lalph", {
|
|
|
202821
202964
|
});
|
|
202822
202965
|
}, scoped$1, provide$1([
|
|
202823
202966
|
ClankaModels.layer,
|
|
202967
|
+
ClankaMuxerLayer,
|
|
202824
202968
|
PromptGen.layer,
|
|
202825
202969
|
GithubCli.layer,
|
|
202826
202970
|
Settings.layer,
|
|
@@ -202925,6 +203069,7 @@ const generateTasks = fnUntraced(function* ({ specsDirectory, specificationPath,
|
|
|
202925
203069
|
});
|
|
202926
203070
|
}, provide$1([
|
|
202927
203071
|
ClankaModels.layer,
|
|
203072
|
+
ClankaMuxerLayer,
|
|
202928
203073
|
Settings.layer,
|
|
202929
203074
|
PromptGen.layer,
|
|
202930
203075
|
Prd.layerProvided.pipe(provideMerge(layerProjectIdPrompt))
|
|
@@ -202997,7 +203142,8 @@ const commandPlan = make$46("plan", {
|
|
|
202997
203142
|
}).pipe(provide$1([
|
|
202998
203143
|
Settings.layer,
|
|
202999
203144
|
CurrentIssueSource.layer,
|
|
203000
|
-
ClankaModels.layer
|
|
203145
|
+
ClankaModels.layer,
|
|
203146
|
+
ClankaMuxerLayer
|
|
203001
203147
|
]));
|
|
203002
203148
|
}, scoped$1, provide$1(Editor.layer))), withSubcommands([commandPlanTasks]));
|
|
203003
203149
|
const plan = fnUntraced(function* (options) {
|
|
@@ -203129,7 +203275,7 @@ const commandEdit = make$46("edit").pipe(withDescription("Open the selected proj
|
|
|
203129
203275
|
const commandSource = make$46("source").pipe(withDescription("Select the issue source to use (e.g. GitHub Issues or Linear). This applies to all projects."), withHandler(() => selectIssueSource), provide(Settings.layer));
|
|
203130
203276
|
//#endregion
|
|
203131
203277
|
//#region package.json
|
|
203132
|
-
var version = "0.3.
|
|
203278
|
+
var version = "0.3.48";
|
|
203133
203279
|
//#endregion
|
|
203134
203280
|
//#region src/commands/projects/ls.ts
|
|
203135
203281
|
const commandProjectsLs = make$46("ls").pipe(withDescription("List configured projects and how they run (enabled state, concurrency, branch, git flow, review agent)."), withHandler(fnUntraced(function* () {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lalph",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.48",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"@octokit/plugin-rest-endpoint-methods": "^17.0.0",
|
|
31
31
|
"@octokit/types": "^16.0.0",
|
|
32
32
|
"@typescript/native-preview": "7.0.0-dev.20260310.1",
|
|
33
|
-
"clanka": "^0.0.
|
|
33
|
+
"clanka": "^0.0.21",
|
|
34
34
|
"concurrently": "^9.2.1",
|
|
35
35
|
"effect": "4.0.0-beta.30",
|
|
36
36
|
"husky": "^9.1.7",
|
package/src/Agents/worker.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { Duration, Effect,
|
|
1
|
+
import { Duration, Effect, Path, pipe, Stream } from "effect"
|
|
2
2
|
import { ChildProcess } from "effect/unstable/process"
|
|
3
3
|
import { Worktree } from "../Worktree.ts"
|
|
4
4
|
import type { CliAgentPreset } from "../domain/CliAgentPreset.ts"
|
|
5
5
|
import { runClanka } from "../Clanka.ts"
|
|
6
6
|
import { ExitCode } from "effect/unstable/process/ChildProcessSpawner"
|
|
7
|
-
import { CurrentTaskRef } from "../TaskTools.ts"
|
|
8
7
|
|
|
9
8
|
export const agentWorker = Effect.fnUntraced(function* (options: {
|
|
10
9
|
readonly stallTimeout: Duration.Duration
|
|
@@ -12,7 +11,6 @@ export const agentWorker = Effect.fnUntraced(function* (options: {
|
|
|
12
11
|
readonly system?: string
|
|
13
12
|
readonly prompt: string
|
|
14
13
|
readonly steer?: Stream.Stream<string>
|
|
15
|
-
readonly taskRef?: CurrentTaskRef["Service"]
|
|
16
14
|
}) {
|
|
17
15
|
const pathService = yield* Path.Path
|
|
18
16
|
const worktree = yield* Worktree
|
|
@@ -26,11 +24,7 @@ export const agentWorker = Effect.fnUntraced(function* (options: {
|
|
|
26
24
|
prompt: options.prompt,
|
|
27
25
|
stallTimeout: options.stallTimeout,
|
|
28
26
|
steer: options.steer,
|
|
29
|
-
})
|
|
30
|
-
options.taskRef
|
|
31
|
-
? Effect.provideService(CurrentTaskRef, options.taskRef)
|
|
32
|
-
: identity,
|
|
33
|
-
)
|
|
27
|
+
})
|
|
34
28
|
return ExitCode(0)
|
|
35
29
|
}
|
|
36
30
|
|
package/src/Clanka.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Agent, OutputFormatter } from "clanka"
|
|
2
|
-
import { Duration, Effect, Stream } from "effect"
|
|
2
|
+
import { Duration, Effect, Layer, Stdio, Stream } from "effect"
|
|
3
3
|
import {
|
|
4
|
+
TaskChooseTools,
|
|
4
5
|
TaskTools,
|
|
5
6
|
TaskToolsHandlers,
|
|
6
7
|
TaskToolsWithChoose,
|
|
@@ -8,8 +9,15 @@ import {
|
|
|
8
9
|
import { ClankaModels, clankaSubagent } from "./ClankaModels.ts"
|
|
9
10
|
import { withStallTimeout } from "./shared/stream.ts"
|
|
10
11
|
|
|
12
|
+
export const ClankaMuxerLayer = Layer.effectDiscard(
|
|
13
|
+
Effect.gen(function* () {
|
|
14
|
+
const muxer = yield* OutputFormatter.Muxer
|
|
15
|
+
const stdio = yield* Stdio.Stdio
|
|
16
|
+
yield* muxer.output.pipe(Stream.run(stdio.stdout()), Effect.forkScoped)
|
|
17
|
+
}),
|
|
18
|
+
).pipe(Layer.provideMerge(OutputFormatter.layerMuxer(OutputFormatter.pretty)))
|
|
19
|
+
|
|
11
20
|
export const runClanka = Effect.fnUntraced(
|
|
12
|
-
/** The working directory to run the agent in */
|
|
13
21
|
function* (options: {
|
|
14
22
|
readonly directory: string
|
|
15
23
|
readonly model: string
|
|
@@ -20,14 +28,18 @@ export const runClanka = Effect.fnUntraced(
|
|
|
20
28
|
readonly withChoose?: boolean | undefined
|
|
21
29
|
}) {
|
|
22
30
|
const models = yield* ClankaModels
|
|
31
|
+
const muxer = yield* OutputFormatter.Muxer
|
|
32
|
+
|
|
23
33
|
const agent = yield* Agent.make({
|
|
24
34
|
...options,
|
|
25
|
-
tools: options.withChoose
|
|
26
|
-
?
|
|
27
|
-
:
|
|
35
|
+
tools: (options.withChoose
|
|
36
|
+
? TaskChooseTools
|
|
37
|
+
: TaskTools) as unknown as typeof TaskToolsWithChoose,
|
|
28
38
|
subagentModel: clankaSubagent(models, options.model),
|
|
29
39
|
}).pipe(Effect.provide(models.get(options.model)))
|
|
30
40
|
|
|
41
|
+
yield* muxer.add(agent.output)
|
|
42
|
+
|
|
31
43
|
let stream = options.stallTimeout
|
|
32
44
|
? withStallTimeout(options.stallTimeout)(agent.output)
|
|
33
45
|
: agent.output
|
|
@@ -45,14 +57,9 @@ export const runClanka = Effect.fnUntraced(
|
|
|
45
57
|
)
|
|
46
58
|
}
|
|
47
59
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
for (const item of out) {
|
|
52
|
-
process.stdout.write(item)
|
|
53
|
-
}
|
|
54
|
-
return Effect.void
|
|
55
|
-
}),
|
|
60
|
+
yield* stream.pipe(
|
|
61
|
+
Stream.runDrain,
|
|
62
|
+
Effect.catchTag("AgentFinished", () => Effect.void),
|
|
56
63
|
)
|
|
57
64
|
},
|
|
58
65
|
Effect.scoped,
|
package/src/PromptGen.ts
CHANGED
|
@@ -90,12 +90,11 @@ Set \`githubPrNumber\` to the PR number if one exists, otherwise use \`null\`.
|
|
|
90
90
|
|
|
91
91
|
const promptChooseClanka = (options: {
|
|
92
92
|
readonly gitFlow: GitFlow["Service"]
|
|
93
|
-
}) =>
|
|
94
|
-
**
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
- Decide which single task to work on next from "listEligibleTasks". This should
|
|
93
|
+
}) => `- Use the "listEligibleTasks" function to view the list of tasks that you can start working on.
|
|
94
|
+
- **NO NOT PARSE THE yaml OUTPUT IN ANY WAY**
|
|
95
|
+
- **DO NOT** implement the task yet.
|
|
96
|
+
- **DO NOT** use the "delegate" function for any step in this workflow
|
|
97
|
+
- After reading through the list of tasks, choose the task to work on. This should
|
|
99
98
|
be the task YOU decide as the most important to work on next, not just the
|
|
100
99
|
first task in the list.${
|
|
101
100
|
options.gitFlow.requiresGithubPr
|
package/src/TaskTools.ts
CHANGED
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
Effect,
|
|
4
4
|
MutableRef,
|
|
5
5
|
Option,
|
|
6
|
+
Random,
|
|
6
7
|
Schema,
|
|
7
8
|
ServiceMap,
|
|
8
9
|
Struct,
|
|
@@ -11,6 +12,7 @@ import { Tool, Toolkit } from "effect/unstable/ai"
|
|
|
11
12
|
import { PrdIssue } from "./domain/PrdIssue.ts"
|
|
12
13
|
import { IssueSource } from "./IssueSource.ts"
|
|
13
14
|
import { CurrentProjectId } from "./Settings.ts"
|
|
15
|
+
import * as Yaml from "yaml"
|
|
14
16
|
|
|
15
17
|
export class ChosenTaskDeferred extends ServiceMap.Reference(
|
|
16
18
|
"lalph/TaskTools/ChosenTaskDeferred",
|
|
@@ -48,6 +50,15 @@ const TaskList = Schema.Array(
|
|
|
48
50
|
}),
|
|
49
51
|
)
|
|
50
52
|
|
|
53
|
+
const toTaskListItem = (issue: PrdIssue) => ({
|
|
54
|
+
id: issue.id ?? "",
|
|
55
|
+
title: issue.title,
|
|
56
|
+
description: issue.description,
|
|
57
|
+
state: issue.state,
|
|
58
|
+
priority: issue.priority,
|
|
59
|
+
blockedBy: issue.blockedBy,
|
|
60
|
+
})
|
|
61
|
+
|
|
51
62
|
export class TaskTools extends Toolkit.make(
|
|
52
63
|
Tool.make("listTasks", {
|
|
53
64
|
description: "Returns the current list of tasks.",
|
|
@@ -86,22 +97,25 @@ export class TaskTools extends Toolkit.make(
|
|
|
86
97
|
}),
|
|
87
98
|
) {}
|
|
88
99
|
|
|
100
|
+
export class TaskChooseTools extends Toolkit.make(
|
|
101
|
+
Tool.make("chooseTask", {
|
|
102
|
+
description: "Choose the task to work on",
|
|
103
|
+
parameters: Schema.Struct({
|
|
104
|
+
taskId: Schema.String,
|
|
105
|
+
githubPrNumber: Schema.optional(Schema.Number),
|
|
106
|
+
}),
|
|
107
|
+
}),
|
|
108
|
+
Tool.make("listEligibleTasks", {
|
|
109
|
+
description:
|
|
110
|
+
"List tasks eligible for being chosen with chooseTask in yaml format.",
|
|
111
|
+
success: Schema.String,
|
|
112
|
+
dependencies: [CurrentProjectId],
|
|
113
|
+
}),
|
|
114
|
+
) {}
|
|
115
|
+
|
|
89
116
|
export class TaskToolsWithChoose extends Toolkit.merge(
|
|
90
117
|
TaskTools,
|
|
91
|
-
|
|
92
|
-
Tool.make("chooseTask", {
|
|
93
|
-
description: "Choose the task to work on",
|
|
94
|
-
parameters: Schema.Struct({
|
|
95
|
-
taskId: Schema.String,
|
|
96
|
-
githubPrNumber: Schema.optional(Schema.Number),
|
|
97
|
-
}),
|
|
98
|
-
}),
|
|
99
|
-
Tool.make("listEligibleTasks", {
|
|
100
|
-
description: "List tasks eligible for being chosen with chooseTask.",
|
|
101
|
-
success: TaskList,
|
|
102
|
-
dependencies: [CurrentProjectId],
|
|
103
|
-
}),
|
|
104
|
-
),
|
|
118
|
+
TaskChooseTools,
|
|
105
119
|
) {}
|
|
106
120
|
|
|
107
121
|
export const TaskToolsHandlers = TaskToolsWithChoose.toLayer(
|
|
@@ -113,29 +127,16 @@ export const TaskToolsHandlers = TaskToolsWithChoose.toLayer(
|
|
|
113
127
|
yield* Effect.log(`Calling "listTasks"`)
|
|
114
128
|
const projectId = yield* CurrentProjectId
|
|
115
129
|
const tasks = yield* source.issues(projectId)
|
|
116
|
-
return tasks.map(
|
|
117
|
-
id: issue.id ?? "",
|
|
118
|
-
title: issue.title,
|
|
119
|
-
description: issue.description,
|
|
120
|
-
state: issue.state,
|
|
121
|
-
priority: issue.priority,
|
|
122
|
-
blockedBy: issue.blockedBy,
|
|
123
|
-
}))
|
|
130
|
+
return tasks.map(toTaskListItem)
|
|
124
131
|
}, Effect.orDie),
|
|
125
132
|
listEligibleTasks: Effect.fn("TaskTools.listEligibleTasks")(function* () {
|
|
126
133
|
yield* Effect.log(`Calling "listEligibleTasks"`)
|
|
127
134
|
const projectId = yield* CurrentProjectId
|
|
128
|
-
const tasks = yield* source.issues(projectId)
|
|
129
|
-
|
|
130
|
-
.
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
title: issue.title,
|
|
134
|
-
description: issue.description,
|
|
135
|
-
state: issue.state,
|
|
136
|
-
priority: issue.priority,
|
|
137
|
-
blockedBy: issue.blockedBy,
|
|
138
|
-
}))
|
|
135
|
+
const tasks = (yield* source.issues(projectId))
|
|
136
|
+
.filter((t) => t.state === "todo" && t.blockedBy.length === 0)
|
|
137
|
+
.map(toTaskListItem)
|
|
138
|
+
const shuffled = yield* Random.shuffle(tasks)
|
|
139
|
+
return Yaml.stringify(shuffled, null, 2)
|
|
139
140
|
}, Effect.orDie),
|
|
140
141
|
chooseTask: Effect.fn("TaskTools.chooseTask")(function* (options) {
|
|
141
142
|
yield* Effect.log(`Calling "chooseTask"`).pipe(
|
|
@@ -11,6 +11,7 @@ import { selectCliAgentPreset } from "../../Presets.ts"
|
|
|
11
11
|
import { CurrentIssueSource } from "../../CurrentIssueSource.ts"
|
|
12
12
|
import type { CliAgentPreset } from "../../domain/CliAgentPreset.ts"
|
|
13
13
|
import { ClankaModels } from "../../ClankaModels.ts"
|
|
14
|
+
import { ClankaMuxerLayer } from "../../Clanka.ts"
|
|
14
15
|
|
|
15
16
|
const specificationPath = Argument.path("spec", {
|
|
16
17
|
pathType: "file",
|
|
@@ -72,6 +73,7 @@ const generateTasks = Effect.fnUntraced(
|
|
|
72
73
|
},
|
|
73
74
|
Effect.provide([
|
|
74
75
|
ClankaModels.layer,
|
|
76
|
+
ClankaMuxerLayer,
|
|
75
77
|
Settings.layer,
|
|
76
78
|
PromptGen.layer,
|
|
77
79
|
Prd.layerProvided.pipe(Layer.provideMerge(layerProjectIdPrompt)),
|
package/src/commands/plan.ts
CHANGED
|
@@ -25,6 +25,7 @@ import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process"
|
|
|
25
25
|
import { parseBranch } from "../shared/git.ts"
|
|
26
26
|
import type { CliAgentPreset } from "../domain/CliAgentPreset.ts"
|
|
27
27
|
import { ClankaModels } from "../ClankaModels.ts"
|
|
28
|
+
import { ClankaMuxerLayer } from "../Clanka.ts"
|
|
28
29
|
|
|
29
30
|
const dangerous = Flag.boolean("dangerous").pipe(
|
|
30
31
|
Flag.withAlias("d"),
|
|
@@ -99,6 +100,7 @@ export const commandPlan = Command.make("plan", {
|
|
|
99
100
|
Settings.layer,
|
|
100
101
|
CurrentIssueSource.layer,
|
|
101
102
|
ClankaModels.layer,
|
|
103
|
+
ClankaMuxerLayer,
|
|
102
104
|
]),
|
|
103
105
|
)
|
|
104
106
|
},
|
package/src/commands/root.ts
CHANGED
|
@@ -52,6 +52,9 @@ import type { ChildProcessSpawner } from "effect/unstable/process"
|
|
|
52
52
|
import { ClankaModels } from "../ClankaModels.ts"
|
|
53
53
|
import type { AiError } from "effect/unstable/ai/AiError"
|
|
54
54
|
import type { PrdIssue } from "../domain/PrdIssue.ts"
|
|
55
|
+
import { CurrentTaskRef } from "../TaskTools.ts"
|
|
56
|
+
import type { OutputFormatter } from "clanka"
|
|
57
|
+
import { ClankaMuxerLayer } from "../Clanka.ts"
|
|
55
58
|
|
|
56
59
|
// Main iteration run logic
|
|
57
60
|
|
|
@@ -88,6 +91,7 @@ const run = Effect.fnUntraced(
|
|
|
88
91
|
| Prd
|
|
89
92
|
| Worktree
|
|
90
93
|
| ClankaModels
|
|
94
|
+
| OutputFormatter.Muxer
|
|
91
95
|
| Scope.Scope
|
|
92
96
|
> {
|
|
93
97
|
const projectId = yield* CurrentProjectId
|
|
@@ -236,7 +240,11 @@ const run = Effect.fnUntraced(
|
|
|
236
240
|
preset: taskPreset,
|
|
237
241
|
prompt: instructions,
|
|
238
242
|
steer,
|
|
239
|
-
}).pipe(
|
|
243
|
+
}).pipe(
|
|
244
|
+
Effect.provideService(CurrentTaskRef, issueRef),
|
|
245
|
+
catchStallInReview,
|
|
246
|
+
Effect.withSpan("Main.agentWorker"),
|
|
247
|
+
)
|
|
240
248
|
yield* Effect.log(`Agent exited with code: ${exitCode}`)
|
|
241
249
|
|
|
242
250
|
// 3. Review task
|
|
@@ -484,6 +492,7 @@ export const commandRoot = Command.make("lalph", {
|
|
|
484
492
|
Effect.scoped,
|
|
485
493
|
Effect.provide([
|
|
486
494
|
ClankaModels.layer,
|
|
495
|
+
ClankaMuxerLayer,
|
|
487
496
|
PromptGen.layer,
|
|
488
497
|
GithubCli.layer,
|
|
489
498
|
Settings.layer,
|