@polka-codes/cli 0.9.33 → 0.9.34

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.
Files changed (2) hide show
  1. package/dist/index.js +860 -1353
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -58608,7 +58608,7 @@ var {
58608
58608
  Help
58609
58609
  } = import__.default;
58610
58610
  // package.json
58611
- var version = "0.9.33";
58611
+ var version = "0.9.34";
58612
58612
 
58613
58613
  // src/commands/chat.ts
58614
58614
  import { readFile as readFile3 } from "node:fs/promises";
@@ -81013,13 +81013,6 @@ function prepareRetries({
81013
81013
  })
81014
81014
  };
81015
81015
  }
81016
- function extractTextContent(content) {
81017
- const parts = content.filter((content2) => content2.type === "text");
81018
- if (parts.length === 0) {
81019
- return;
81020
- }
81021
- return parts.map((content2) => content2.text).join("");
81022
- }
81023
81016
  var DefaultGeneratedFile = class {
81024
81017
  constructor({
81025
81018
  data,
@@ -81311,519 +81304,6 @@ var originalGenerateId = createIdGenerator({
81311
81304
  prefix: "aitxt",
81312
81305
  size: 24
81313
81306
  });
81314
- async function generateText({
81315
- model: modelArg,
81316
- tools,
81317
- toolChoice,
81318
- system,
81319
- prompt,
81320
- messages,
81321
- maxRetries: maxRetriesArg,
81322
- abortSignal,
81323
- headers,
81324
- stopWhen = stepCountIs(1),
81325
- experimental_output: output,
81326
- experimental_telemetry: telemetry,
81327
- providerOptions,
81328
- experimental_activeTools,
81329
- activeTools = experimental_activeTools,
81330
- experimental_prepareStep,
81331
- prepareStep = experimental_prepareStep,
81332
- experimental_repairToolCall: repairToolCall,
81333
- experimental_download: download2,
81334
- experimental_context,
81335
- _internal: {
81336
- generateId: generateId3 = originalGenerateId,
81337
- currentDate = () => /* @__PURE__ */ new Date
81338
- } = {},
81339
- onStepFinish,
81340
- ...settings
81341
- }) {
81342
- const model = resolveLanguageModel(modelArg);
81343
- const stopConditions = asArray(stopWhen);
81344
- const { maxRetries, retry } = prepareRetries({
81345
- maxRetries: maxRetriesArg,
81346
- abortSignal
81347
- });
81348
- const callSettings = prepareCallSettings(settings);
81349
- const baseTelemetryAttributes = getBaseTelemetryAttributes({
81350
- model,
81351
- telemetry,
81352
- headers,
81353
- settings: { ...callSettings, maxRetries }
81354
- });
81355
- const initialPrompt = await standardizePrompt({
81356
- system,
81357
- prompt,
81358
- messages
81359
- });
81360
- const tracer = getTracer(telemetry);
81361
- try {
81362
- return await recordSpan({
81363
- name: "ai.generateText",
81364
- attributes: selectTelemetryAttributes({
81365
- telemetry,
81366
- attributes: {
81367
- ...assembleOperationName({
81368
- operationId: "ai.generateText",
81369
- telemetry
81370
- }),
81371
- ...baseTelemetryAttributes,
81372
- "ai.model.provider": model.provider,
81373
- "ai.model.id": model.modelId,
81374
- "ai.prompt": {
81375
- input: () => JSON.stringify({ system, prompt, messages })
81376
- }
81377
- }
81378
- }),
81379
- tracer,
81380
- fn: async (span) => {
81381
- var _a172, _b8, _c, _d, _e, _f, _g;
81382
- const callSettings2 = prepareCallSettings(settings);
81383
- let currentModelResponse;
81384
- let clientToolCalls = [];
81385
- let clientToolOutputs = [];
81386
- const responseMessages = [];
81387
- const steps = [];
81388
- do {
81389
- const stepInputMessages = [
81390
- ...initialPrompt.messages,
81391
- ...responseMessages
81392
- ];
81393
- const prepareStepResult = await (prepareStep == null ? undefined : prepareStep({
81394
- model,
81395
- steps,
81396
- stepNumber: steps.length,
81397
- messages: stepInputMessages
81398
- }));
81399
- const promptMessages = await convertToLanguageModelPrompt({
81400
- prompt: {
81401
- system: (_a172 = prepareStepResult == null ? undefined : prepareStepResult.system) != null ? _a172 : initialPrompt.system,
81402
- messages: (_b8 = prepareStepResult == null ? undefined : prepareStepResult.messages) != null ? _b8 : stepInputMessages
81403
- },
81404
- supportedUrls: await model.supportedUrls,
81405
- download: download2
81406
- });
81407
- const stepModel = resolveLanguageModel((_c = prepareStepResult == null ? undefined : prepareStepResult.model) != null ? _c : model);
81408
- const { toolChoice: stepToolChoice, tools: stepTools } = prepareToolsAndToolChoice({
81409
- tools,
81410
- toolChoice: (_d = prepareStepResult == null ? undefined : prepareStepResult.toolChoice) != null ? _d : toolChoice,
81411
- activeTools: (_e = prepareStepResult == null ? undefined : prepareStepResult.activeTools) != null ? _e : activeTools
81412
- });
81413
- currentModelResponse = await retry(() => {
81414
- var _a18;
81415
- return recordSpan({
81416
- name: "ai.generateText.doGenerate",
81417
- attributes: selectTelemetryAttributes({
81418
- telemetry,
81419
- attributes: {
81420
- ...assembleOperationName({
81421
- operationId: "ai.generateText.doGenerate",
81422
- telemetry
81423
- }),
81424
- ...baseTelemetryAttributes,
81425
- "ai.model.provider": stepModel.provider,
81426
- "ai.model.id": stepModel.modelId,
81427
- "ai.prompt.messages": {
81428
- input: () => stringifyForTelemetry(promptMessages)
81429
- },
81430
- "ai.prompt.tools": {
81431
- input: () => stepTools == null ? undefined : stepTools.map((tool3) => JSON.stringify(tool3))
81432
- },
81433
- "ai.prompt.toolChoice": {
81434
- input: () => stepToolChoice != null ? JSON.stringify(stepToolChoice) : undefined
81435
- },
81436
- "gen_ai.system": stepModel.provider,
81437
- "gen_ai.request.model": stepModel.modelId,
81438
- "gen_ai.request.frequency_penalty": settings.frequencyPenalty,
81439
- "gen_ai.request.max_tokens": settings.maxOutputTokens,
81440
- "gen_ai.request.presence_penalty": settings.presencePenalty,
81441
- "gen_ai.request.stop_sequences": settings.stopSequences,
81442
- "gen_ai.request.temperature": (_a18 = settings.temperature) != null ? _a18 : undefined,
81443
- "gen_ai.request.top_k": settings.topK,
81444
- "gen_ai.request.top_p": settings.topP
81445
- }
81446
- }),
81447
- tracer,
81448
- fn: async (span2) => {
81449
- var _a19, _b22, _c2, _d2, _e2, _f2, _g2, _h;
81450
- const result = await stepModel.doGenerate({
81451
- ...callSettings2,
81452
- tools: stepTools,
81453
- toolChoice: stepToolChoice,
81454
- responseFormat: output == null ? undefined : output.responseFormat,
81455
- prompt: promptMessages,
81456
- providerOptions,
81457
- abortSignal,
81458
- headers
81459
- });
81460
- const responseData = {
81461
- id: (_b22 = (_a19 = result.response) == null ? undefined : _a19.id) != null ? _b22 : generateId3(),
81462
- timestamp: (_d2 = (_c2 = result.response) == null ? undefined : _c2.timestamp) != null ? _d2 : currentDate(),
81463
- modelId: (_f2 = (_e2 = result.response) == null ? undefined : _e2.modelId) != null ? _f2 : stepModel.modelId,
81464
- headers: (_g2 = result.response) == null ? undefined : _g2.headers,
81465
- body: (_h = result.response) == null ? undefined : _h.body
81466
- };
81467
- span2.setAttributes(selectTelemetryAttributes({
81468
- telemetry,
81469
- attributes: {
81470
- "ai.response.finishReason": result.finishReason,
81471
- "ai.response.text": {
81472
- output: () => extractTextContent(result.content)
81473
- },
81474
- "ai.response.toolCalls": {
81475
- output: () => {
81476
- const toolCalls = asToolCalls(result.content);
81477
- return toolCalls == null ? undefined : JSON.stringify(toolCalls);
81478
- }
81479
- },
81480
- "ai.response.id": responseData.id,
81481
- "ai.response.model": responseData.modelId,
81482
- "ai.response.timestamp": responseData.timestamp.toISOString(),
81483
- "ai.response.providerMetadata": JSON.stringify(result.providerMetadata),
81484
- "ai.usage.promptTokens": result.usage.inputTokens,
81485
- "ai.usage.completionTokens": result.usage.outputTokens,
81486
- "gen_ai.response.finish_reasons": [result.finishReason],
81487
- "gen_ai.response.id": responseData.id,
81488
- "gen_ai.response.model": responseData.modelId,
81489
- "gen_ai.usage.input_tokens": result.usage.inputTokens,
81490
- "gen_ai.usage.output_tokens": result.usage.outputTokens
81491
- }
81492
- }));
81493
- return { ...result, response: responseData };
81494
- }
81495
- });
81496
- });
81497
- const stepToolCalls = await Promise.all(currentModelResponse.content.filter((part) => part.type === "tool-call").map((toolCall) => parseToolCall({
81498
- toolCall,
81499
- tools,
81500
- repairToolCall,
81501
- system,
81502
- messages: stepInputMessages
81503
- })));
81504
- for (const toolCall of stepToolCalls) {
81505
- if (toolCall.invalid) {
81506
- continue;
81507
- }
81508
- const tool3 = tools[toolCall.toolName];
81509
- if ((tool3 == null ? undefined : tool3.onInputAvailable) != null) {
81510
- await tool3.onInputAvailable({
81511
- input: toolCall.input,
81512
- toolCallId: toolCall.toolCallId,
81513
- messages: stepInputMessages,
81514
- abortSignal,
81515
- experimental_context
81516
- });
81517
- }
81518
- }
81519
- const invalidToolCalls = stepToolCalls.filter((toolCall) => toolCall.invalid && toolCall.dynamic);
81520
- clientToolOutputs = [];
81521
- for (const toolCall of invalidToolCalls) {
81522
- clientToolOutputs.push({
81523
- type: "tool-error",
81524
- toolCallId: toolCall.toolCallId,
81525
- toolName: toolCall.toolName,
81526
- input: toolCall.input,
81527
- error: getErrorMessage2(toolCall.error),
81528
- dynamic: true
81529
- });
81530
- }
81531
- clientToolCalls = stepToolCalls.filter((toolCall) => !toolCall.providerExecuted);
81532
- if (tools != null) {
81533
- clientToolOutputs.push(...await executeTools({
81534
- toolCalls: clientToolCalls.filter((toolCall) => !toolCall.invalid),
81535
- tools,
81536
- tracer,
81537
- telemetry,
81538
- messages: stepInputMessages,
81539
- abortSignal,
81540
- experimental_context
81541
- }));
81542
- }
81543
- const stepContent = asContent({
81544
- content: currentModelResponse.content,
81545
- toolCalls: stepToolCalls,
81546
- toolOutputs: clientToolOutputs
81547
- });
81548
- responseMessages.push(...toResponseMessages({
81549
- content: stepContent,
81550
- tools
81551
- }));
81552
- const currentStepResult = new DefaultStepResult({
81553
- content: stepContent,
81554
- finishReason: currentModelResponse.finishReason,
81555
- usage: currentModelResponse.usage,
81556
- warnings: currentModelResponse.warnings,
81557
- providerMetadata: currentModelResponse.providerMetadata,
81558
- request: (_f = currentModelResponse.request) != null ? _f : {},
81559
- response: {
81560
- ...currentModelResponse.response,
81561
- messages: structuredClone(responseMessages)
81562
- }
81563
- });
81564
- logWarnings((_g = currentModelResponse.warnings) != null ? _g : []);
81565
- steps.push(currentStepResult);
81566
- await (onStepFinish == null ? undefined : onStepFinish(currentStepResult));
81567
- } while (clientToolCalls.length > 0 && clientToolOutputs.length === clientToolCalls.length && !await isStopConditionMet({ stopConditions, steps }));
81568
- span.setAttributes(selectTelemetryAttributes({
81569
- telemetry,
81570
- attributes: {
81571
- "ai.response.finishReason": currentModelResponse.finishReason,
81572
- "ai.response.text": {
81573
- output: () => extractTextContent(currentModelResponse.content)
81574
- },
81575
- "ai.response.toolCalls": {
81576
- output: () => {
81577
- const toolCalls = asToolCalls(currentModelResponse.content);
81578
- return toolCalls == null ? undefined : JSON.stringify(toolCalls);
81579
- }
81580
- },
81581
- "ai.response.providerMetadata": JSON.stringify(currentModelResponse.providerMetadata),
81582
- "ai.usage.promptTokens": currentModelResponse.usage.inputTokens,
81583
- "ai.usage.completionTokens": currentModelResponse.usage.outputTokens
81584
- }
81585
- }));
81586
- const lastStep = steps[steps.length - 1];
81587
- return new DefaultGenerateTextResult({
81588
- steps,
81589
- resolvedOutput: await (output == null ? undefined : output.parseOutput({ text: lastStep.text }, {
81590
- response: lastStep.response,
81591
- usage: lastStep.usage,
81592
- finishReason: lastStep.finishReason
81593
- }))
81594
- });
81595
- }
81596
- });
81597
- } catch (error43) {
81598
- throw wrapGatewayError(error43);
81599
- }
81600
- }
81601
- async function executeTools({
81602
- toolCalls,
81603
- tools,
81604
- tracer,
81605
- telemetry,
81606
- messages,
81607
- abortSignal,
81608
- experimental_context
81609
- }) {
81610
- const toolOutputs = await Promise.all(toolCalls.map(async ({ toolCallId, toolName, input }) => {
81611
- const tool3 = tools[toolName];
81612
- if ((tool3 == null ? undefined : tool3.execute) == null) {
81613
- return;
81614
- }
81615
- return recordSpan({
81616
- name: "ai.toolCall",
81617
- attributes: selectTelemetryAttributes({
81618
- telemetry,
81619
- attributes: {
81620
- ...assembleOperationName({
81621
- operationId: "ai.toolCall",
81622
- telemetry
81623
- }),
81624
- "ai.toolCall.name": toolName,
81625
- "ai.toolCall.id": toolCallId,
81626
- "ai.toolCall.args": {
81627
- output: () => JSON.stringify(input)
81628
- }
81629
- }
81630
- }),
81631
- tracer,
81632
- fn: async (span) => {
81633
- try {
81634
- const stream = executeTool({
81635
- execute: tool3.execute.bind(tool3),
81636
- input,
81637
- options: {
81638
- toolCallId,
81639
- messages,
81640
- abortSignal,
81641
- experimental_context
81642
- }
81643
- });
81644
- let output;
81645
- for await (const part of stream) {
81646
- if (part.type === "final") {
81647
- output = part.output;
81648
- }
81649
- }
81650
- try {
81651
- span.setAttributes(selectTelemetryAttributes({
81652
- telemetry,
81653
- attributes: {
81654
- "ai.toolCall.result": {
81655
- output: () => JSON.stringify(output)
81656
- }
81657
- }
81658
- }));
81659
- } catch (ignored) {}
81660
- return {
81661
- type: "tool-result",
81662
- toolCallId,
81663
- toolName,
81664
- input,
81665
- output,
81666
- dynamic: tool3.type === "dynamic"
81667
- };
81668
- } catch (error43) {
81669
- recordErrorOnSpan(span, error43);
81670
- return {
81671
- type: "tool-error",
81672
- toolCallId,
81673
- toolName,
81674
- input,
81675
- error: error43,
81676
- dynamic: tool3.type === "dynamic"
81677
- };
81678
- }
81679
- }
81680
- });
81681
- }));
81682
- return toolOutputs.filter((output) => output != null);
81683
- }
81684
- var DefaultGenerateTextResult = class {
81685
- constructor(options) {
81686
- this.steps = options.steps;
81687
- this.resolvedOutput = options.resolvedOutput;
81688
- }
81689
- get finalStep() {
81690
- return this.steps[this.steps.length - 1];
81691
- }
81692
- get content() {
81693
- return this.finalStep.content;
81694
- }
81695
- get text() {
81696
- return this.finalStep.text;
81697
- }
81698
- get files() {
81699
- return this.finalStep.files;
81700
- }
81701
- get reasoningText() {
81702
- return this.finalStep.reasoningText;
81703
- }
81704
- get reasoning() {
81705
- return this.finalStep.reasoning;
81706
- }
81707
- get toolCalls() {
81708
- return this.finalStep.toolCalls;
81709
- }
81710
- get staticToolCalls() {
81711
- return this.finalStep.staticToolCalls;
81712
- }
81713
- get dynamicToolCalls() {
81714
- return this.finalStep.dynamicToolCalls;
81715
- }
81716
- get toolResults() {
81717
- return this.finalStep.toolResults;
81718
- }
81719
- get staticToolResults() {
81720
- return this.finalStep.staticToolResults;
81721
- }
81722
- get dynamicToolResults() {
81723
- return this.finalStep.dynamicToolResults;
81724
- }
81725
- get sources() {
81726
- return this.finalStep.sources;
81727
- }
81728
- get finishReason() {
81729
- return this.finalStep.finishReason;
81730
- }
81731
- get warnings() {
81732
- return this.finalStep.warnings;
81733
- }
81734
- get providerMetadata() {
81735
- return this.finalStep.providerMetadata;
81736
- }
81737
- get response() {
81738
- return this.finalStep.response;
81739
- }
81740
- get request() {
81741
- return this.finalStep.request;
81742
- }
81743
- get usage() {
81744
- return this.finalStep.usage;
81745
- }
81746
- get totalUsage() {
81747
- return this.steps.reduce((totalUsage, step) => {
81748
- return addLanguageModelUsage(totalUsage, step.usage);
81749
- }, {
81750
- inputTokens: undefined,
81751
- outputTokens: undefined,
81752
- totalTokens: undefined,
81753
- reasoningTokens: undefined,
81754
- cachedInputTokens: undefined
81755
- });
81756
- }
81757
- get experimental_output() {
81758
- if (this.resolvedOutput == null) {
81759
- throw new NoOutputSpecifiedError;
81760
- }
81761
- return this.resolvedOutput;
81762
- }
81763
- };
81764
- function asToolCalls(content) {
81765
- const parts = content.filter((part) => part.type === "tool-call");
81766
- if (parts.length === 0) {
81767
- return;
81768
- }
81769
- return parts.map((toolCall) => ({
81770
- toolCallId: toolCall.toolCallId,
81771
- toolName: toolCall.toolName,
81772
- input: toolCall.input
81773
- }));
81774
- }
81775
- function asContent({
81776
- content,
81777
- toolCalls,
81778
- toolOutputs
81779
- }) {
81780
- return [
81781
- ...content.map((part) => {
81782
- switch (part.type) {
81783
- case "text":
81784
- case "reasoning":
81785
- case "source":
81786
- return part;
81787
- case "file": {
81788
- return {
81789
- type: "file",
81790
- file: new DefaultGeneratedFile(part)
81791
- };
81792
- }
81793
- case "tool-call": {
81794
- return toolCalls.find((toolCall) => toolCall.toolCallId === part.toolCallId);
81795
- }
81796
- case "tool-result": {
81797
- const toolCall = toolCalls.find((toolCall2) => toolCall2.toolCallId === part.toolCallId);
81798
- if (toolCall == null) {
81799
- throw new Error(`Tool call ${part.toolCallId} not found.`);
81800
- }
81801
- if (part.isError) {
81802
- return {
81803
- type: "tool-error",
81804
- toolCallId: part.toolCallId,
81805
- toolName: part.toolName,
81806
- input: toolCall.input,
81807
- error: part.result,
81808
- providerExecuted: true,
81809
- dynamic: toolCall.dynamic
81810
- };
81811
- }
81812
- return {
81813
- type: "tool-result",
81814
- toolCallId: part.toolCallId,
81815
- toolName: part.toolName,
81816
- input: toolCall.input,
81817
- output: part.result,
81818
- providerExecuted: true,
81819
- dynamic: toolCall.dynamic
81820
- };
81821
- }
81822
- }
81823
- }),
81824
- ...toolOutputs
81825
- ];
81826
- }
81827
81307
  function prepareHeaders(headers, defaultHeaders) {
81828
81308
  const responseHeaders = new Headers(headers != null ? headers : {});
81829
81309
  for (const [key2, value] of Object.entries(defaultHeaders)) {
@@ -86633,20 +86113,29 @@ class MultiAgent {
86633
86113
  var parseJsonFromMarkdown = (markdown) => {
86634
86114
  const jsonRegex = /```(?:json)?\n([\s\S]*?)\n```/;
86635
86115
  const match = markdown.match(jsonRegex);
86116
+ const tryParse = (str) => {
86117
+ try {
86118
+ let parsed = JSON.parse(str);
86119
+ if (typeof parsed === "string") {
86120
+ try {
86121
+ parsed = JSON.parse(parsed);
86122
+ } catch {}
86123
+ }
86124
+ return { success: true, data: parsed };
86125
+ } catch (e) {
86126
+ const error43 = e instanceof Error ? e.message : String(e);
86127
+ return { success: false, error: `Failed to parse JSON: ${error43}` };
86128
+ }
86129
+ };
86636
86130
  if (match?.[1]) {
86637
86131
  const content = match[1].trim();
86638
- let parsed = JSON.parse(content);
86639
- if (typeof parsed === "string") {
86640
- try {
86641
- parsed = JSON.parse(parsed);
86642
- } catch {}
86643
- }
86644
- return parsed;
86132
+ return tryParse(content);
86645
86133
  }
86646
- try {
86647
- return JSON.parse(markdown);
86648
- } catch (_error) {}
86649
- return markdown;
86134
+ const parseResult = tryParse(markdown);
86135
+ if (parseResult.success) {
86136
+ return parseResult;
86137
+ }
86138
+ return { success: false, error: "No JSON object found in the string." };
86650
86139
  };
86651
86140
  // ../core/src/config.ts
86652
86141
  var toolFormatSchema = exports_external.enum(["native", "polka-codes"]).optional();
@@ -86946,189 +86435,8 @@ var createNewProject_default = {
86946
86435
  agent: "architect"
86947
86436
  };
86948
86437
 
86949
- // ../core/src/AiTool/generateGitCommitMessage.ts
86950
- var prompt2 = `
86951
- You are an advanced assistant specialized in creating concise and accurate Git commit messages. When you receive:
86952
- - A Git diff inside the <tool_input> tag.
86953
- - Additional user-supplied context inside the <tool_input_context> tag (if any).
86954
-
86955
- You will produce a single commit message enclosed within <tool_output> tags. The commit message must accurately reflect the changes shown in the diff and should be clear, descriptive, and devoid of unnecessary or repeated information. If a context is provided, it MUST be incorporated into the commit message.
86956
-
86957
- Here’s an example of the input and the expected output format:
86958
-
86959
- <tool_input>
86960
- --- a/example_file.py
86961
- +++ b/example_file.py
86962
- @@ -10,7 +10,7 @@ def example_function():
86963
- - print("Old behavior")
86964
- + print("New behavior")
86965
- </tool_input>
86966
- <tool_input_context>
86967
- Changing print statement to update the user-facing message.
86968
- </tool_input_context>
86969
-
86970
- Example Output:
86971
-
86972
- <tool_output>
86973
- Update print statement for revised user-facing message
86974
- </tool_output>
86975
-
86976
- Follow the same structure for any new input. Never repeat questions; focus on generating a concise commit message that captures the essence of the changes.
86977
- `;
86978
- var generateGitCommitMessage_default = {
86979
- name: "generateGitCommitMessage",
86980
- description: "Generates git commit messages from git diff output",
86981
- prompt: prompt2,
86982
- formatInput: (params) => {
86983
- let ret = `<tool_input>
86984
- ${params.diff}
86985
- </tool_input>`;
86986
- if (params.context) {
86987
- ret += `
86988
- <tool_input_context>
86989
- ${params.context}
86990
- </tool_input_context>`;
86991
- }
86992
- return ret;
86993
- },
86994
- parseOutput: (output) => {
86995
- const regex = /<tool_output>([\s\S]*)<\/tool_output>/gm;
86996
- const match = regex.exec(output);
86997
- if (match) {
86998
- return match[1];
86999
- }
87000
- throw new Error(`Could not parse output:
87001
- ${output}`);
87002
- }
87003
- };
87004
-
87005
- // ../core/src/AiTool/generateGithubPullRequestDetails.ts
87006
- var prompt3 = `
87007
- # Generate Github Pull Request Details
87008
-
87009
- You are given:
87010
- - A branch name in <tool_input_branch_name>.
87011
- - An optional context message in <tool_input_context> (which may or may not be present).
87012
- - All commit messages combined in <tool_input_commit_messages>.
87013
- - All diffs combined in <tool_input_commit_diff>.
87014
-
87015
- Your task:
87016
- 1. Consider the optional context (if provided).
87017
- - If an issue number is found, add "Closes #xxx" at the beginning of the PR description
87018
- - IMPORTANT: Use ONLY the exact format "Closes #xxx" at the beginning of the description
87019
- - DO NOT use variations like "Closes issue #xxx" or other formats
87020
- 2. Analyze the combined commit messages and diffs.
87021
- 3. Produce a single GitHub Pull Request title.
87022
- 4. Produce a Pull Request description that explains the changes.
87023
-
87024
- Use the following template for the Pull Request description:
87025
-
87026
- ---
87027
- **Context (if provided)**:
87028
- - Acknowledge any guiding concerns or instructions.
87029
-
87030
- **Summary of Changes**:
87031
- - Provide a concise list or overview of what changed.
87032
-
87033
- **Highlights of Changed Code**:
87034
- - Mention only the specific sections or functionalities updated, without showing full surrounding context.
87035
-
87036
- **Additional Information (if needed)**:
87037
- - Testing steps (if applicable).
87038
- - Any notes or caveats.
87039
-
87040
- ---
87041
-
87042
- Output format:
87043
- <tool_output>
87044
- <tool_output_pr_title>YOUR PR TITLE HERE</tool_output_pr_title>
87045
- <tool_output_pr_description>
87046
- YOUR PR DESCRIPTION HERE
87047
- </tool_output_pr_description>
87048
- </tool_output>
87049
-
87050
- Below is an **example** of the input and output:
87051
-
87052
- Example Input:
87053
- <tool_input>
87054
- <tool_input_branch_name>feature/refactor-logging</tool_input_branch_name>
87055
- <tool_input_context>Implementing changes for issue #123 - Focus on clean code and maintainability</tool_input_context>
87056
- <tool_input_commit_messages>
87057
- Remove debug logs
87058
- Refactor order validation logic
87059
- </tool_input_commit_messages>
87060
- <tool_input_commit_diff>
87061
- diff --git a/user_service.py b/user_service.py
87062
- - print("Debug info")
87063
- + # Removed debug print statements
87064
-
87065
- diff --git a/order_service.py b/order_service.py
87066
- - if is_valid_order(order):
87067
- - process_order(order)
87068
- + validate_and_process(order)
87069
- </tool_input_commit_diff>
87070
- </tool_input>
87071
-
87072
- Example Output:
87073
- <tool_output>
87074
- <tool_output_pr_title>Refactor Order Validation and Remove Debug Logs</tool_output_pr_title>
87075
- <tool_output_pr_description>
87076
- Closes #123
87077
-
87078
- **Context**:
87079
- - Implementing changes for issue #123 - Focus on clean code and maintainability
87080
-
87081
- **Summary of Changes**:
87082
- - Refactored order validation logic to use a new \`validate_and_process\` method.
87083
- - Removed debug print statements from \`user_service.py\`.
87084
-
87085
- **Highlights of Changed Code**:
87086
- - \`order_service.py\`: Replaced direct call to \`process_order\` with \`validate_and_process\`.
87087
- - \`user_service.py\`: Removed \`print("Debug info")\`.
87088
- </tool_output_pr_description>
87089
- </tool_output>
87090
-
87091
- ---
87092
-
87093
- Use the above format whenever you receive <tool_input> that may include a branch name, an optional context, aggregated commit messages in a single tag, and a combined diff in a single tag. Provide your final output strictly in <tool_output> with <tool_output_pr_title> and <tool_output_pr_description>. Only highlight the changed code and avoid including the context around the changes in the description.
87094
- `;
87095
- var generateGithubPullRequestDetails_default = {
87096
- name: "generateGithubPullRequestDetails",
87097
- description: "Generates a GitHub pull request title and description from git commits",
87098
- prompt: prompt3,
87099
- formatInput: (params) => {
87100
- return `<tool_input>
87101
- <tool_input_branch_name>${params.branchName}</tool_input_branch_name>${params.context ? `
87102
- <tool_input_context>${params.context}</tool_input_context>` : ""}
87103
- <tool_input_commit_messages>${params.commitMessages}</tool_input_commit_messages>
87104
- <tool_input_commit_diff>${params.commitDiff}</tool_input_commit_diff>
87105
- </tool_input>`;
87106
- },
87107
- parseOutput: (output) => {
87108
- const regex = /<tool_output>([\s\S]*)<\/tool_output>/gm;
87109
- const match = regex.exec(output);
87110
- if (!match) {
87111
- throw new Error(`Could not parse output:
87112
- ${output}`);
87113
- }
87114
- const [, outputContent] = match;
87115
- const titleRegex = /<tool_output_pr_title>([\s\S]*)<\/tool_output_pr_title>/gm;
87116
- const titleMatch = titleRegex.exec(outputContent);
87117
- const descriptionRegex = /<tool_output_pr_description>([\s\S]*)<\/tool_output_pr_description>/gm;
87118
- const descriptionMatch = descriptionRegex.exec(outputContent);
87119
- if (titleMatch && descriptionMatch) {
87120
- return {
87121
- title: titleMatch[1],
87122
- description: descriptionMatch[1]
87123
- };
87124
- }
87125
- throw new Error(`Could not parse output:
87126
- ${output}`);
87127
- }
87128
- };
87129
-
87130
86438
  // ../core/src/AiTool/generateProjectConfig.ts
87131
- var prompt4 = `
86439
+ var prompt2 = `
87132
86440
  Role: Analyzer agent
87133
86441
  Goal: Produce a valid polkacodes YAML configuration for the project.
87134
86442
 
@@ -87175,7 +86483,7 @@ excludeFiles: # only files likely to hold secrets
87175
86483
  var generateProjectConfig_default = {
87176
86484
  name: "generateProjectConfig",
87177
86485
  description: "Analyzes project files to generate polkacodes config sections",
87178
- prompt: prompt4,
86486
+ prompt: prompt2,
87179
86487
  formatInput: () => {
87180
86488
  return "";
87181
86489
  },
@@ -87186,21 +86494,6 @@ var generateProjectConfig_default = {
87186
86494
  };
87187
86495
 
87188
86496
  // ../core/src/AiTool/index.ts
87189
- var executeTool2 = async (definition, ai, params, usageMeter) => {
87190
- const resp = await generateText({
87191
- model: ai,
87192
- temperature: 0,
87193
- system: definition.prompt,
87194
- messages: [
87195
- {
87196
- role: "user",
87197
- content: definition.formatInput(params)
87198
- }
87199
- ]
87200
- });
87201
- usageMeter.addUsage(ai, resp);
87202
- return definition.parseOutput(resp.text);
87203
- };
87204
86497
  var executeMultiAgentTool = async (definition, agent, params) => {
87205
86498
  const exitReason = await agent.startTask({
87206
86499
  agentName: definition.agent,
@@ -87212,18 +86505,11 @@ var executeMultiAgentTool = async (definition, agent, params) => {
87212
86505
  }
87213
86506
  throw new Error(`Tool execution failed: ${exitReason.type}`);
87214
86507
  };
87215
- var makeTool = (definition) => {
87216
- return async (ai, params, usageMeter) => {
87217
- return executeTool2(definition, ai, params, usageMeter);
87218
- };
87219
- };
87220
86508
  var makeMultiAgentTool = (definition) => {
87221
86509
  return async (agent, params) => {
87222
86510
  return executeMultiAgentTool(definition, agent, params);
87223
86511
  };
87224
86512
  };
87225
- var generateGitCommitMessage = makeTool(generateGitCommitMessage_default);
87226
- var generateGithubPullRequestDetails = makeTool(generateGithubPullRequestDetails_default);
87227
86513
  var generateProjectConfig = makeMultiAgentTool(generateProjectConfig_default);
87228
86514
  var createNewProject = makeMultiAgentTool(createNewProject_default);
87229
86515
  // ../core/src/workflow/utils.ts
@@ -87264,9 +86550,7 @@ var makeAgentStepSpecHandler = (getModelFn) => ({
87264
86550
  try {
87265
86551
  const model = await getModelFn(step, context);
87266
86552
  const parameters = context.parameters ?? {};
87267
- const budget = step.budget ?? parameters?.budget;
87268
- const maxMessages = step.maxMessages ?? parameters?.maxMessages;
87269
- const usageMeter = new UsageMeter({}, { maxMessages, maxCost: budget });
86553
+ const usageMeter = parameters?.usageMeter ?? new UsageMeter;
87270
86554
  const toolFormat = step.toolFormat ?? parameters.toolFormat ?? "native";
87271
86555
  const policies2 = parameters.policies ?? [];
87272
86556
  const modelParameters = { ...parameters.modelParameters ?? {}, ...step.modelParameters ?? {} };
@@ -87294,7 +86578,9 @@ var makeAgentStepSpecHandler = (getModelFn) => ({
87294
86578
  parameters: modelParameters,
87295
86579
  scripts: parameters.scripts,
87296
86580
  callback: context.agentCallback,
87297
- requireToolUse: false
86581
+ requireToolUse: false,
86582
+ retryCount: parameters.retryCount,
86583
+ requestTimeoutSeconds: parameters.requestTimeoutSeconds
87298
86584
  });
87299
86585
  } else {
87300
86586
  if (!step.systemPrompt) {
@@ -87316,7 +86602,9 @@ var makeAgentStepSpecHandler = (getModelFn) => ({
87316
86602
  toolFormat,
87317
86603
  parameters: modelParameters,
87318
86604
  usageMeter,
87319
- requireToolUse: false
86605
+ requireToolUse: false,
86606
+ retryCount: parameters.retryCount,
86607
+ requestTimeoutSeconds: parameters.requestTimeoutSeconds
87320
86608
  });
87321
86609
  }
87322
86610
  };
@@ -87345,7 +86633,7 @@ var makeAgentStepSpecHandler = (getModelFn) => ({
87345
86633
  if (context.verbose && context.verbose >= 1) {
87346
86634
  logger.log(`[agent-step] Agent exited with reason:`, exitReason);
87347
86635
  }
87348
- const handleExitReason = (reason) => {
86636
+ const handleExitReason = async (reason) => {
87349
86637
  switch (reason.type) {
87350
86638
  case "Pause":
87351
86639
  return { type: "paused", state: { messages: agent.messages } };
@@ -87354,24 +86642,34 @@ var makeAgentStepSpecHandler = (getModelFn) => ({
87354
86642
  case "Exit" /* Exit */: {
87355
86643
  const raw = reason.message;
87356
86644
  if (step.parseOutput) {
87357
- try {
87358
- const parsed = step.parseOutput(raw);
86645
+ const result = step.parseOutput(raw);
86646
+ if (result.success) {
87359
86647
  if (step.outputSchema) {
87360
- const validationResult = step.outputSchema.safeParse(parsed);
86648
+ const validationResult = step.outputSchema.safeParse(result.data);
87361
86649
  if (validationResult.success) {
87362
86650
  return { type: "success", output: validationResult.data };
87363
86651
  }
87364
- return {
87365
- type: "error",
87366
- error: new Error(`Output validation failed: ${validationResult.error.toString()}`)
87367
- };
86652
+ let errorMessage2 = `Output validation failed: ${validationResult.error.toString()}`;
86653
+ if (step.outputSchema) {
86654
+ errorMessage2 += `
86655
+
86656
+ Expected JSON schema:
86657
+ ${JSON.stringify(toJSONSchema(step.outputSchema), null, 2)}`;
86658
+ }
86659
+ const newReason2 = await agent.continueTask(errorMessage2);
86660
+ return handleExitReason(newReason2);
87368
86661
  }
87369
- return { type: "success", output: parsed };
87370
- } catch (e) {
87371
- const error43 = e instanceof Error ? e : new Error(String(e));
87372
- error43.message = `Failed to parse agent output with parseOutput: ${error43.message}`;
87373
- return { type: "error", error: error43 };
86662
+ return { type: "success", output: result.data };
87374
86663
  }
86664
+ let errorMessage = result.error ?? "Invalid format.";
86665
+ if (step.outputSchema) {
86666
+ errorMessage += `
86667
+
86668
+ Expected JSON schema:
86669
+ ${JSON.stringify(toJSONSchema(step.outputSchema), null, 2)}`;
86670
+ }
86671
+ const newReason = await agent.continueTask(errorMessage);
86672
+ return handleExitReason(newReason);
87375
86673
  } else if (step.outputSchema) {
87376
86674
  try {
87377
86675
  const output = JSON.parse(raw);
@@ -87379,14 +86677,22 @@ var makeAgentStepSpecHandler = (getModelFn) => ({
87379
86677
  if (validationResult.success) {
87380
86678
  return { type: "success", output: validationResult.data };
87381
86679
  }
87382
- return {
87383
- type: "error",
87384
- error: new Error(`Output validation failed: ${validationResult.error.toString()}`)
87385
- };
86680
+ let errorMessage = `Output validation failed: ${validationResult.error.toString()}`;
86681
+ errorMessage += `
86682
+
86683
+ Expected JSON schema:
86684
+ ${JSON.stringify(toJSONSchema(step.outputSchema), null, 2)}`;
86685
+ const newReason = await agent.continueTask(errorMessage);
86686
+ return handleExitReason(newReason);
87386
86687
  } catch (e) {
87387
86688
  const error43 = e instanceof Error ? e : new Error(String(e));
87388
- error43.message = `Failed to parse agent output as JSON: ${error43.message}`;
87389
- return { type: "error", error: error43 };
86689
+ let errorMessage = `Failed to parse agent output as JSON: ${error43.message}`;
86690
+ errorMessage += `
86691
+
86692
+ Expected JSON schema:
86693
+ ${JSON.stringify(toJSONSchema(step.outputSchema), null, 2)}`;
86694
+ const newReason = await agent.continueTask(errorMessage);
86695
+ return handleExitReason(newReason);
87390
86696
  }
87391
86697
  }
87392
86698
  return { type: "success", output: reason };
@@ -87406,7 +86712,7 @@ var makeAgentStepSpecHandler = (getModelFn) => ({
87406
86712
  };
87407
86713
  }
87408
86714
  };
87409
- return handleExitReason(exitReason);
86715
+ return await handleExitReason(exitReason);
87410
86716
  } catch (e) {
87411
86717
  return { type: "error", error: e instanceof Error ? e : new Error(String(e)) };
87412
86718
  }
@@ -88445,13 +87751,13 @@ function convertToString(data) {
88445
87751
  });
88446
87752
  }
88447
87753
  async function convertToAnthropicMessagesPrompt({
88448
- prompt: prompt5,
87754
+ prompt: prompt3,
88449
87755
  sendReasoning,
88450
87756
  warnings
88451
87757
  }) {
88452
87758
  var _a18, _b8, _c, _d, _e;
88453
87759
  const betas = /* @__PURE__ */ new Set;
88454
- const blocks = groupIntoBlocks(prompt5);
87760
+ const blocks = groupIntoBlocks(prompt3);
88455
87761
  let system = undefined;
88456
87762
  const messages = [];
88457
87763
  async function shouldEnableCitations(providerMetadata) {
@@ -88810,10 +88116,10 @@ async function convertToAnthropicMessagesPrompt({
88810
88116
  betas
88811
88117
  };
88812
88118
  }
88813
- function groupIntoBlocks(prompt5) {
88119
+ function groupIntoBlocks(prompt3) {
88814
88120
  const blocks = [];
88815
88121
  let currentBlock = undefined;
88816
- for (const message of prompt5) {
88122
+ for (const message of prompt3) {
88817
88123
  const { role } = message;
88818
88124
  switch (role) {
88819
88125
  case "system": {
@@ -88960,7 +88266,7 @@ var AnthropicMessagesLanguageModel = class {
88960
88266
  return (_c = (_b8 = (_a18 = this.config).supportedUrls) == null ? undefined : _b8.call(_a18)) != null ? _c : {};
88961
88267
  }
88962
88268
  async getArgs({
88963
- prompt: prompt5,
88269
+ prompt: prompt3,
88964
88270
  maxOutputTokens = 4096,
88965
88271
  temperature,
88966
88272
  topP,
@@ -89021,7 +88327,7 @@ var AnthropicMessagesLanguageModel = class {
89021
88327
  schema: anthropicProviderOptions
89022
88328
  });
89023
88329
  const { prompt: messagesPrompt, betas: messagesBetas } = await convertToAnthropicMessagesPrompt({
89024
- prompt: prompt5,
88330
+ prompt: prompt3,
89025
88331
  sendReasoning: (_a18 = anthropicOptions == null ? undefined : anthropicOptions.sendReasoning) != null ? _a18 : true,
89026
88332
  warnings
89027
88333
  });
@@ -89111,7 +88417,7 @@ var AnthropicMessagesLanguageModel = class {
89111
88417
  var _a18, _b8, _c;
89112
88418
  return (_c = (_b8 = (_a18 = this.config).transformRequestBody) == null ? undefined : _b8.call(_a18, args)) != null ? _c : args;
89113
88419
  }
89114
- extractCitationDocuments(prompt5) {
88420
+ extractCitationDocuments(prompt3) {
89115
88421
  const isCitationPart = (part) => {
89116
88422
  var _a18, _b8;
89117
88423
  if (part.type !== "file") {
@@ -89124,7 +88430,7 @@ var AnthropicMessagesLanguageModel = class {
89124
88430
  const citationsConfig = anthropic2 == null ? undefined : anthropic2.citations;
89125
88431
  return (_b8 = citationsConfig == null ? undefined : citationsConfig.enabled) != null ? _b8 : false;
89126
88432
  };
89127
- return prompt5.filter((message) => message.role === "user").flatMap((message) => message.content).filter(isCitationPart).map((part) => {
88433
+ return prompt3.filter((message) => message.role === "user").flatMap((message) => message.content).filter(isCitationPart).map((part) => {
89128
88434
  var _a18;
89129
88435
  const filePart = part;
89130
88436
  return {
@@ -90471,9 +89777,9 @@ function getOpenAIMetadata(message) {
90471
89777
  var _a18, _b8;
90472
89778
  return (_b8 = (_a18 = message == null ? undefined : message.providerOptions) == null ? undefined : _a18.openaiCompatible) != null ? _b8 : {};
90473
89779
  }
90474
- function convertToOpenAICompatibleChatMessages(prompt5) {
89780
+ function convertToOpenAICompatibleChatMessages(prompt3) {
90475
89781
  const messages = [];
90476
- for (const { role, content, ...message } of prompt5) {
89782
+ for (const { role, content, ...message } of prompt3) {
90477
89783
  const metadata = getOpenAIMetadata({ ...message });
90478
89784
  switch (role) {
90479
89785
  case "system": {
@@ -90698,7 +90004,7 @@ var OpenAICompatibleChatLanguageModel = class {
90698
90004
  return (_c = (_b8 = (_a18 = this.config).supportedUrls) == null ? undefined : _b8.call(_a18)) != null ? _c : {};
90699
90005
  }
90700
90006
  async getArgs({
90701
- prompt: prompt5,
90007
+ prompt: prompt3,
90702
90008
  maxOutputTokens,
90703
90009
  temperature,
90704
90010
  topP,
@@ -90762,7 +90068,7 @@ var OpenAICompatibleChatLanguageModel = class {
90762
90068
  seed,
90763
90069
  ...Object.fromEntries(Object.entries((_d = providerOptions == null ? undefined : providerOptions[this.providerOptionsName]) != null ? _d : {}).filter(([key2]) => !Object.keys(openaiCompatibleProviderOptions.shape).includes(key2))),
90764
90070
  reasoning_effort: compatibleOptions.reasoningEffort,
90765
- messages: convertToOpenAICompatibleChatMessages(prompt5),
90071
+ messages: convertToOpenAICompatibleChatMessages(prompt3),
90766
90072
  tools: openaiTools,
90767
90073
  tool_choice: openaiToolChoice
90768
90074
  },
@@ -92410,13 +91716,13 @@ function convertJSONSchemaToOpenAPISchema(jsonSchema2) {
92410
91716
  function isEmptyObjectSchema(jsonSchema2) {
92411
91717
  return jsonSchema2 != null && typeof jsonSchema2 === "object" && jsonSchema2.type === "object" && (jsonSchema2.properties == null || Object.keys(jsonSchema2.properties).length === 0) && !jsonSchema2.additionalProperties;
92412
91718
  }
92413
- function convertToGoogleGenerativeAIMessages(prompt5, options) {
91719
+ function convertToGoogleGenerativeAIMessages(prompt3, options) {
92414
91720
  var _a18;
92415
91721
  const systemInstructionParts = [];
92416
91722
  const contents = [];
92417
91723
  let systemMessagesAllowed = true;
92418
91724
  const isGemmaModel = (_a18 = options == null ? undefined : options.isGemmaModel) != null ? _a18 : false;
92419
- for (const { role, content } of prompt5) {
91725
+ for (const { role, content } of prompt3) {
92420
91726
  switch (role) {
92421
91727
  case "system": {
92422
91728
  if (!systemMessagesAllowed) {
@@ -92814,7 +92120,7 @@ var GoogleGenerativeAILanguageModel = class {
92814
92120
  return (_c = (_b8 = (_a18 = this.config).supportedUrls) == null ? undefined : _b8.call(_a18)) != null ? _c : {};
92815
92121
  }
92816
92122
  async getArgs({
92817
- prompt: prompt5,
92123
+ prompt: prompt3,
92818
92124
  maxOutputTokens,
92819
92125
  temperature,
92820
92126
  topP,
@@ -92842,7 +92148,7 @@ var GoogleGenerativeAILanguageModel = class {
92842
92148
  });
92843
92149
  }
92844
92150
  const isGemmaModel = this.modelId.toLowerCase().startsWith("gemma-");
92845
- const { contents, systemInstruction } = convertToGoogleGenerativeAIMessages(prompt5, { isGemmaModel });
92151
+ const { contents, systemInstruction } = convertToGoogleGenerativeAIMessages(prompt3, { isGemmaModel });
92846
92152
  const {
92847
92153
  tools: googleTools2,
92848
92154
  toolConfig: googleToolConfig,
@@ -93465,7 +92771,7 @@ var GoogleVertexImageModel = class {
93465
92771
  return this.config.provider;
93466
92772
  }
93467
92773
  async doGenerate({
93468
- prompt: prompt5,
92774
+ prompt: prompt3,
93469
92775
  n,
93470
92776
  size,
93471
92777
  aspectRatio,
@@ -93489,7 +92795,7 @@ var GoogleVertexImageModel = class {
93489
92795
  schema: vertexImageProviderOptionsSchema
93490
92796
  });
93491
92797
  const body = {
93492
- instances: [{ prompt: prompt5 }],
92798
+ instances: [{ prompt: prompt3 }],
93493
92799
  parameters: {
93494
92800
  sampleCount: n,
93495
92801
  ...aspectRatio != null ? { aspectRatio } : {},
@@ -94291,12 +93597,12 @@ function withoutTrailingSlash5(url2) {
94291
93597
 
94292
93598
  // ../../node_modules/@ai-sdk/openai/dist/index.mjs
94293
93599
  function convertToOpenAIChatMessages({
94294
- prompt: prompt5,
93600
+ prompt: prompt3,
94295
93601
  systemMessageMode = "system"
94296
93602
  }) {
94297
93603
  const messages = [];
94298
93604
  const warnings = [];
94299
- for (const { role, content } of prompt5) {
93605
+ for (const { role, content } of prompt3) {
94300
93606
  switch (role) {
94301
93607
  case "system": {
94302
93608
  switch (systemMessageMode) {
@@ -94652,7 +93958,7 @@ var OpenAIChatLanguageModel = class {
94652
93958
  return this.config.provider;
94653
93959
  }
94654
93960
  async getArgs({
94655
- prompt: prompt5,
93961
+ prompt: prompt3,
94656
93962
  maxOutputTokens,
94657
93963
  temperature,
94658
93964
  topP,
@@ -94688,7 +93994,7 @@ var OpenAIChatLanguageModel = class {
94688
93994
  });
94689
93995
  }
94690
93996
  const { messages, warnings: messageWarnings } = convertToOpenAIChatMessages({
94691
- prompt: prompt5,
93997
+ prompt: prompt3,
94692
93998
  systemMessageMode: getSystemMessageMode(this.modelId)
94693
93999
  });
94694
94000
  warnings.push(...messageWarnings);
@@ -95259,23 +94565,23 @@ var reasoningModels = {
95259
94565
  }
95260
94566
  };
95261
94567
  function convertToOpenAICompletionPrompt({
95262
- prompt: prompt5,
94568
+ prompt: prompt3,
95263
94569
  user = "user",
95264
94570
  assistant = "assistant"
95265
94571
  }) {
95266
94572
  let text2 = "";
95267
- if (prompt5[0].role === "system") {
95268
- text2 += `${prompt5[0].content}
94573
+ if (prompt3[0].role === "system") {
94574
+ text2 += `${prompt3[0].content}
95269
94575
 
95270
94576
  `;
95271
- prompt5 = prompt5.slice(1);
94577
+ prompt3 = prompt3.slice(1);
95272
94578
  }
95273
- for (const { role, content } of prompt5) {
94579
+ for (const { role, content } of prompt3) {
95274
94580
  switch (role) {
95275
94581
  case "system": {
95276
94582
  throw new InvalidPromptError({
95277
94583
  message: "Unexpected system message in prompt: ${content}",
95278
- prompt: prompt5
94584
+ prompt: prompt3
95279
94585
  });
95280
94586
  }
95281
94587
  case "user": {
@@ -95351,7 +94657,7 @@ var OpenAICompletionLanguageModel = class {
95351
94657
  return this.config.provider;
95352
94658
  }
95353
94659
  async getArgs({
95354
- prompt: prompt5,
94660
+ prompt: prompt3,
95355
94661
  maxOutputTokens,
95356
94662
  temperature,
95357
94663
  topP,
@@ -95394,7 +94700,7 @@ var OpenAICompletionLanguageModel = class {
95394
94700
  details: "JSON response format is not supported."
95395
94701
  });
95396
94702
  }
95397
- const { prompt: completionPrompt, stopSequences } = convertToOpenAICompletionPrompt({ prompt: prompt5 });
94703
+ const { prompt: completionPrompt, stopSequences } = convertToOpenAICompletionPrompt({ prompt: prompt3 });
95398
94704
  const stop = [...stopSequences != null ? stopSequences : [], ...userStopSequences != null ? userStopSequences : []];
95399
94705
  return {
95400
94706
  args: {
@@ -95679,7 +94985,7 @@ var OpenAIImageModel = class {
95679
94985
  return this.config.provider;
95680
94986
  }
95681
94987
  async doGenerate({
95682
- prompt: prompt5,
94988
+ prompt: prompt3,
95683
94989
  n,
95684
94990
  size,
95685
94991
  aspectRatio,
@@ -95709,7 +95015,7 @@ var OpenAIImageModel = class {
95709
95015
  headers: combineHeaders6(this.config.headers(), headers),
95710
95016
  body: {
95711
95017
  model: this.modelId,
95712
- prompt: prompt5,
95018
+ prompt: prompt3,
95713
95019
  n,
95714
95020
  size,
95715
95021
  ...(_d = providerOptions.openai) != null ? _d : {},
@@ -95905,13 +95211,13 @@ var openaiTranscriptionResponseSchema = exports_external.object({
95905
95211
  })).nullish()
95906
95212
  });
95907
95213
  async function convertToOpenAIResponsesMessages({
95908
- prompt: prompt5,
95214
+ prompt: prompt3,
95909
95215
  systemMessageMode
95910
95216
  }) {
95911
95217
  var _a18, _b8, _c, _d, _e, _f;
95912
95218
  const messages = [];
95913
95219
  const warnings = [];
95914
- for (const { role, content } of prompt5) {
95220
+ for (const { role, content } of prompt3) {
95915
95221
  switch (role) {
95916
95222
  case "system": {
95917
95223
  switch (systemMessageMode) {
@@ -96200,7 +95506,7 @@ var OpenAIResponsesLanguageModel = class {
96200
95506
  presencePenalty,
96201
95507
  frequencyPenalty,
96202
95508
  seed,
96203
- prompt: prompt5,
95509
+ prompt: prompt3,
96204
95510
  providerOptions,
96205
95511
  tools: tools2,
96206
95512
  toolChoice,
@@ -96231,7 +95537,7 @@ var OpenAIResponsesLanguageModel = class {
96231
95537
  warnings.push({ type: "unsupported-setting", setting: "stopSequences" });
96232
95538
  }
96233
95539
  const { messages, warnings: messageWarnings } = await convertToOpenAIResponsesMessages({
96234
- prompt: prompt5,
95540
+ prompt: prompt3,
96235
95541
  systemMessageMode: modelConfig.systemMessageMode
96236
95542
  });
96237
95543
  warnings.push(...messageWarnings);
@@ -97402,13 +96708,13 @@ var symbol54 = Symbol.for(marker54);
97402
96708
  var _a54;
97403
96709
  var InvalidPromptError2 = class extends AISDKError2 {
97404
96710
  constructor({
97405
- prompt: prompt5,
96711
+ prompt: prompt3,
97406
96712
  message,
97407
96713
  cause
97408
96714
  }) {
97409
96715
  super({ name: name44, message: `Invalid prompt: ${message}`, cause });
97410
96716
  this[_a54] = true;
97411
- this.prompt = prompt5;
96717
+ this.prompt = prompt3;
97412
96718
  }
97413
96719
  static isInstance(error43) {
97414
96720
  return AISDKError2.hasMarker(error43, marker54);
@@ -98171,10 +97477,10 @@ function getCacheControl2(providerMetadata) {
98171
97477
  const openrouter2 = providerMetadata == null ? undefined : providerMetadata.openrouter;
98172
97478
  return (_c = (_b8 = (_a153 = openrouter2 == null ? undefined : openrouter2.cacheControl) != null ? _a153 : openrouter2 == null ? undefined : openrouter2.cache_control) != null ? _b8 : anthropic2 == null ? undefined : anthropic2.cacheControl) != null ? _c : anthropic2 == null ? undefined : anthropic2.cache_control;
98173
97479
  }
98174
- function convertToOpenRouterChatMessages(prompt5) {
97480
+ function convertToOpenRouterChatMessages(prompt3) {
98175
97481
  var _a153, _b8, _c;
98176
97482
  const messages = [];
98177
- for (const { role, content, providerOptions } of prompt5) {
97483
+ for (const { role, content, providerOptions } of prompt3) {
98178
97484
  switch (role) {
98179
97485
  case "system": {
98180
97486
  messages.push({
@@ -98484,7 +97790,7 @@ var OpenRouterChatLanguageModel = class {
98484
97790
  this.config = config3;
98485
97791
  }
98486
97792
  getArgs({
98487
- prompt: prompt5,
97793
+ prompt: prompt3,
98488
97794
  maxOutputTokens,
98489
97795
  temperature,
98490
97796
  topP,
@@ -98515,7 +97821,7 @@ var OpenRouterChatLanguageModel = class {
98515
97821
  stop: stopSequences,
98516
97822
  response_format: responseFormat,
98517
97823
  top_k: topK,
98518
- messages: convertToOpenRouterChatMessages(prompt5),
97824
+ messages: convertToOpenRouterChatMessages(prompt3),
98519
97825
  include_reasoning: this.settings.includeReasoning,
98520
97826
  reasoning: this.settings.reasoning,
98521
97827
  usage: this.settings.usage,
@@ -99023,27 +98329,27 @@ var OpenRouterChatLanguageModel = class {
99023
98329
  }
99024
98330
  };
99025
98331
  function convertToOpenRouterCompletionPrompt({
99026
- prompt: prompt5,
98332
+ prompt: prompt3,
99027
98333
  inputFormat,
99028
98334
  user = "user",
99029
98335
  assistant = "assistant"
99030
98336
  }) {
99031
- if (inputFormat === "prompt" && prompt5.length === 1 && prompt5[0] && prompt5[0].role === "user" && prompt5[0].content.length === 1 && prompt5[0].content[0] && prompt5[0].content[0].type === "text") {
99032
- return { prompt: prompt5[0].content[0].text };
98337
+ if (inputFormat === "prompt" && prompt3.length === 1 && prompt3[0] && prompt3[0].role === "user" && prompt3[0].content.length === 1 && prompt3[0].content[0] && prompt3[0].content[0].type === "text") {
98338
+ return { prompt: prompt3[0].content[0].text };
99033
98339
  }
99034
98340
  let text2 = "";
99035
- if (prompt5[0] && prompt5[0].role === "system") {
99036
- text2 += `${prompt5[0].content}
98341
+ if (prompt3[0] && prompt3[0].role === "system") {
98342
+ text2 += `${prompt3[0].content}
99037
98343
 
99038
98344
  `;
99039
- prompt5 = prompt5.slice(1);
98345
+ prompt3 = prompt3.slice(1);
99040
98346
  }
99041
- for (const { role, content } of prompt5) {
98347
+ for (const { role, content } of prompt3) {
99042
98348
  switch (role) {
99043
98349
  case "system": {
99044
98350
  throw new InvalidPromptError2({
99045
98351
  message: `Unexpected system message in prompt: ${content}`,
99046
- prompt: prompt5
98352
+ prompt: prompt3
99047
98353
  });
99048
98354
  }
99049
98355
  case "user": {
@@ -99170,7 +98476,7 @@ var OpenRouterCompletionLanguageModel = class {
99170
98476
  this.config = config3;
99171
98477
  }
99172
98478
  getArgs({
99173
- prompt: prompt5,
98479
+ prompt: prompt3,
99174
98480
  maxOutputTokens,
99175
98481
  temperature,
99176
98482
  topP,
@@ -99184,7 +98490,7 @@ var OpenRouterCompletionLanguageModel = class {
99184
98490
  toolChoice
99185
98491
  }) {
99186
98492
  const { prompt: completionPrompt } = convertToOpenRouterCompletionPrompt({
99187
- prompt: prompt5,
98493
+ prompt: prompt3,
99188
98494
  inputFormat: "prompt"
99189
98495
  });
99190
98496
  if (tools2 == null ? undefined : tools2.length) {
@@ -99837,23 +99143,23 @@ var ollamaFailedResponseHandler = createJsonErrorResponseHandler8({
99837
99143
  errorToMessage: (data) => data.error.message
99838
99144
  });
99839
99145
  function convertToOllamaCompletionPrompt({
99840
- prompt: prompt5,
99146
+ prompt: prompt3,
99841
99147
  user = "user",
99842
99148
  assistant = "assistant"
99843
99149
  }) {
99844
99150
  let text2 = "";
99845
- if (prompt5[0].role === "system") {
99846
- text2 += `${prompt5[0].content}
99151
+ if (prompt3[0].role === "system") {
99152
+ text2 += `${prompt3[0].content}
99847
99153
 
99848
99154
  `;
99849
- prompt5 = prompt5.slice(1);
99155
+ prompt3 = prompt3.slice(1);
99850
99156
  }
99851
- for (const { role, content } of prompt5) {
99157
+ for (const { role, content } of prompt3) {
99852
99158
  switch (role) {
99853
99159
  case "system": {
99854
99160
  throw new InvalidPromptError({
99855
99161
  message: "Unexpected system message in prompt: ${content}",
99856
- prompt: prompt5
99162
+ prompt: prompt3
99857
99163
  });
99858
99164
  }
99859
99165
  case "user": {
@@ -99951,7 +99257,7 @@ var OllamaCompletionLanguageModel = class {
99951
99257
  return this.config.provider;
99952
99258
  }
99953
99259
  async getArgs({
99954
- prompt: prompt5,
99260
+ prompt: prompt3,
99955
99261
  maxOutputTokens,
99956
99262
  temperature,
99957
99263
  topP,
@@ -99991,7 +99297,7 @@ var OllamaCompletionLanguageModel = class {
99991
99297
  details: "JSON response format is not supported."
99992
99298
  });
99993
99299
  }
99994
- const { prompt: completionPrompt, stopSequences } = convertToOllamaCompletionPrompt({ prompt: prompt5 });
99300
+ const { prompt: completionPrompt, stopSequences } = convertToOllamaCompletionPrompt({ prompt: prompt3 });
99995
99301
  const stop = [...stopSequences != null ? stopSequences : [], ...userStopSequences != null ? userStopSequences : []];
99996
99302
  return {
99997
99303
  args: {
@@ -100205,12 +99511,12 @@ var ollamaTextEmbeddingResponseSchema = exports_external.object({
100205
99511
  prompt_eval_count: exports_external.number()
100206
99512
  });
100207
99513
  function convertToOllamaResponsesMessages({
100208
- prompt: prompt5,
99514
+ prompt: prompt3,
100209
99515
  systemMessageMode
100210
99516
  }) {
100211
99517
  const messages = [];
100212
99518
  const warnings = [];
100213
- for (const { role, content } of prompt5) {
99519
+ for (const { role, content } of prompt3) {
100214
99520
  switch (role) {
100215
99521
  case "system": {
100216
99522
  switch (systemMessageMode) {
@@ -100340,11 +99646,11 @@ function convertToOllamaResponsesMessages({
100340
99646
  return { messages, warnings };
100341
99647
  }
100342
99648
  function convertToOllamaChatMessages({
100343
- prompt: prompt5,
99649
+ prompt: prompt3,
100344
99650
  systemMessageMode = "system"
100345
99651
  }) {
100346
99652
  const messages = [];
100347
- for (const { role, content } of prompt5) {
99653
+ for (const { role, content } of prompt3) {
100348
99654
  switch (role) {
100349
99655
  case "system": {
100350
99656
  switch (systemMessageMode) {
@@ -100540,7 +99846,7 @@ var OllamaRequestBuilder = class {
100540
99846
  presencePenalty,
100541
99847
  frequencyPenalty,
100542
99848
  seed,
100543
- prompt: prompt5,
99849
+ prompt: prompt3,
100544
99850
  providerOptions,
100545
99851
  tools: tools2,
100546
99852
  toolChoice,
@@ -100554,14 +99860,14 @@ var OllamaRequestBuilder = class {
100554
99860
  stopSequences
100555
99861
  });
100556
99862
  const { messages, warnings: messageWarnings } = convertToOllamaResponsesMessages({
100557
- prompt: prompt5,
99863
+ prompt: prompt3,
100558
99864
  systemMessageMode: "system"
100559
99865
  });
100560
99866
  warnings.push(...messageWarnings);
100561
99867
  const ollamaOptions = await this.parseProviderOptions(providerOptions);
100562
99868
  const baseArgs = this.buildBaseArgs({
100563
99869
  modelId,
100564
- prompt: prompt5,
99870
+ prompt: prompt3,
100565
99871
  temperature,
100566
99872
  topP,
100567
99873
  maxOutputTokens,
@@ -100613,7 +99919,7 @@ var OllamaRequestBuilder = class {
100613
99919
  }
100614
99920
  buildBaseArgs({
100615
99921
  modelId,
100616
- prompt: prompt5,
99922
+ prompt: prompt3,
100617
99923
  temperature,
100618
99924
  topP,
100619
99925
  maxOutputTokens,
@@ -100624,7 +99930,7 @@ var OllamaRequestBuilder = class {
100624
99930
  return {
100625
99931
  model: modelId,
100626
99932
  messages: convertToOllamaChatMessages({
100627
- prompt: prompt5,
99933
+ prompt: prompt3,
100628
99934
  systemMessageMode: "system"
100629
99935
  }),
100630
99936
  temperature,
@@ -106668,7 +105974,7 @@ Tool error:`, event.tool));
106668
105974
  // src/options.ts
106669
105975
  var import_lodash4 = __toESM(require_lodash(), 1);
106670
105976
  function addSharedOptions(command2) {
106671
- return command2.option("-c --config <paths>", "Path to config file(s)", (value, prev) => prev.concat(value), []).option("--api-provider <provider>", "API provider").option("--model <model>", "Model ID").option("--api-key <key>", "API key").option("--max-messages <iterations>", "Maximum number of messages to send.", Number.parseInt).option("--budget <budget>", "Budget for the AI service.", Number.parseFloat).option("--retry-count <count>", "Number of retries for failed requests.", Number.parseInt).option("--request-timeout-seconds <seconds>", "Request timeout in seconds.", Number.parseInt).option("-v --verbose", "Enable verbose output. Use -v for level 1, -vv for level 2", (_value, prev) => prev + 1, 0).option("-d --base-dir <path>", "Base directory to run commands in").option("--agent <agent>", "Initial agent to use (default: architect)").option("--file <path...>", "File to include in the task").option("--silent", "Enable silent mode");
105977
+ return command2.option("-c --config <paths>", "Path to config file(s)", (value, prev) => prev.concat(value), []).option("--api-provider <provider>", "API provider").option("--model <model>", "Model ID").option("--api-key <key>", "API key").option("--max-messages <iterations>", "Maximum number of messages to send.", Number.parseInt).option("--budget <budget>", "Budget for the AI service.", Number.parseFloat).option("-v --verbose", "Enable verbose output. Use -v for level 1, -vv for level 2", (_value, prev) => prev + 1, 0).option("-d --base-dir <path>", "Base directory to run commands in").option("--agent <agent>", "Initial agent to use (default: architect)").option("--file <path...>", "File to include in the task").option("--silent", "Enable silent mode");
106672
105978
  }
106673
105979
  function parseOptions(options, cwdArg, home = os2.homedir(), env2 = getEnv()) {
106674
105980
  let cwd = cwdArg;
@@ -106678,12 +105984,6 @@ function parseOptions(options, cwdArg, home = os2.homedir(), env2 = getEnv()) {
106678
105984
  console.log("Changed working directory to", cwd);
106679
105985
  }
106680
105986
  const config4 = loadConfig(options.config, cwd, home) ?? {};
106681
- if (options.retryCount !== undefined) {
106682
- config4.retryCount = options.retryCount;
106683
- }
106684
- if (options.requestTimeoutSeconds !== undefined) {
106685
- config4.requestTimeoutSeconds = options.requestTimeoutSeconds;
106686
- }
106687
105987
  const defaultProvider = options.apiProvider || env2.POLKA_API_PROVIDER || config4.defaultProvider;
106688
105988
  const defaultModel = options.model || env2.POLKA_MODEL || config4.defaultModel;
106689
105989
  if (defaultProvider && defaultModel) {
@@ -106782,7 +106082,7 @@ class Runner {
106782
106082
  multiAgent;
106783
106083
  constructor(options) {
106784
106084
  this.#options = options;
106785
- this.usageMeter = new UsageMeter(import_lodash5.merge(prices_default, options.config.prices ?? {}), {
106085
+ this.usageMeter = options.externalUsageMeter ?? new UsageMeter(import_lodash5.merge(prices_default, options.config.prices ?? {}), {
106786
106086
  maxMessages: options.maxMessageCount ?? 0,
106787
106087
  maxCost: options.budget ?? 0
106788
106088
  });
@@ -107090,7 +106390,11 @@ var runChat = async (opts, command2) => {
107090
106390
  };
107091
106391
 
107092
106392
  // src/commands/commit.ts
107093
- import { execSync, spawnSync as spawnSync2 } from "node:child_process";
106393
+ import { spawnSync as spawnSync3 } from "node:child_process";
106394
+
106395
+ // src/runWorkflow.ts
106396
+ import { Console } from "node:console";
106397
+ import os5 from "node:os";
107094
106398
  var import_lodash7 = __toESM(require_lodash(), 1);
107095
106399
 
107096
106400
  // ../../node_modules/ora/index.js
@@ -108182,414 +107486,94 @@ function ora(options) {
108182
107486
  return new Ora(options);
108183
107487
  }
108184
107488
 
108185
- // src/commands/commit.ts
108186
- var commitCommand = new Command("commit").description("Create a commit with AI-generated message").option("-a, --all", "Stage all files before committing").argument("[message]", "Optional context for the commit message generation").action(async (message, localOptions, command2) => {
108187
- const options = command2.parent?.opts() ?? {};
108188
- const { providerConfig, config: config4 } = parseOptions(options);
108189
- const commandConfig = providerConfig.getConfigForCommand("commit");
108190
- if (!commandConfig || !commandConfig.provider || !commandConfig.model) {
108191
- console.error('Error: No provider specified. Please run "polka config" to configure your AI provider.');
108192
- process.exit(1);
108193
- }
108194
- console.log("Provider:", commandConfig.provider);
108195
- console.log("Model:", commandConfig.model);
108196
- const spinner = ora("Gathering information...").start();
108197
- const usage = new UsageMeter(import_lodash7.merge(prices_default, config4.prices ?? {}));
108198
- try {
108199
- const status = execSync("git status --porcelain").toString();
108200
- const stagedFiles = status.split(`
108201
- `).filter((line) => line.match(/^[MADRC]/));
108202
- if (stagedFiles.length === 0) {
108203
- if (localOptions.all) {
108204
- execSync("git add .");
108205
- } else {
108206
- spinner.stopAndPersist();
108207
- await new Promise((resolve7) => setTimeout(resolve7, 10));
108208
- const addAll = await esm_default2({
108209
- message: "No staged files found. Do you want to stage all files?"
108210
- });
108211
- spinner.start();
108212
- if (addAll) {
108213
- execSync("git add .");
108214
- } else {
108215
- console.error("Error: No files to commit");
108216
- process.exit(1);
108217
- }
108218
- }
108219
- }
108220
- const diff = execSync("git diff --cached -U50").toString();
108221
- spinner.text = "Generating commit message...";
108222
- const llm = getModel(commandConfig);
108223
- const commitMessage = await generateGitCommitMessage(llm, { diff, context: message }, usage);
108224
- usage.printUsage();
108225
- spinner.succeed("Commit message generated");
108226
- console.log(`
108227
- Commit message:
108228
- ${commitMessage}`);
108229
- try {
108230
- spawnSync2("git", ["commit", "-m", commitMessage], { stdio: "inherit" });
108231
- } catch {
108232
- console.error("Error: Commit failed");
107489
+ // src/runWorkflow.ts
107490
+ async function runWorkflowCommand(commandName, workflow3, command2, workflowInput, handleSuccess, options = {}) {
107491
+ const parentOptions = command2.parent?.opts() ?? {};
107492
+ const { providerConfig, config: config4, verbose } = parseOptions(parentOptions);
107493
+ let commandConfig;
107494
+ if (commandName !== "init") {
107495
+ commandConfig = providerConfig.getConfigForCommand(commandName);
107496
+ if (!commandConfig || !commandConfig.provider || !commandConfig.model) {
107497
+ console.error(`Error: No provider specified for ${commandName}. Please run "polka config" to configure your AI provider.`);
108233
107498
  process.exit(1);
108234
107499
  }
108235
- } catch (error43) {
108236
- if (error43.constructor.name === "ExitPromptError") {
108237
- spinner.stop();
108238
- console.log(`
108239
- Commit cancelled by user.`);
108240
- process.exit(0);
108241
- } else {
108242
- spinner.fail("An unexpected error occurred.");
108243
- console.error("Error:", error43);
108244
- process.exit(1);
107500
+ const { json: json3 = false } = options;
107501
+ if (!json3) {
107502
+ console.log("Provider:", commandConfig.provider);
107503
+ console.log("Model:", commandConfig.model);
108245
107504
  }
108246
107505
  }
108247
- });
108248
-
108249
- // src/commands/create.ts
108250
- import { existsSync as existsSync3 } from "node:fs";
108251
- import { mkdir as mkdir2, stat } from "node:fs/promises";
108252
- import { join as join3 } from "node:path";
108253
- var askForPath = async (projectName) => {
108254
- let targetPath = join3(process.cwd(), projectName);
108255
- while (true) {
108256
- const confirmPath = await esm_default2({
108257
- message: `Do you want to create project at ${targetPath}?`,
108258
- default: true
108259
- });
108260
- if (confirmPath) {
108261
- if (existsSync3(targetPath)) {
108262
- const targetStat = await stat(targetPath);
108263
- if (targetStat.isDirectory()) {
108264
- const confirmPath2 = await esm_default2({
108265
- message: `Directory ${targetPath} already exists. Do you want to overwrite it?`,
108266
- default: true
108267
- });
108268
- if (confirmPath2) {
108269
- return targetPath;
108270
- }
108271
- } else {
108272
- console.error("Target path is not a directory");
108273
- }
108274
- } else {
108275
- return targetPath;
108276
- }
107506
+ const { json: json2 = false, suppressUsagePrint = false } = options;
107507
+ const agentStepHandler = makeAgentStepSpecHandler(async (_step, _context) => {
107508
+ if (commandName === "init") {
107509
+ throw new Error("Agent steps are not supported in the init workflow via runWorkflowCommand.");
108277
107510
  }
108278
- const inputPath = await esm_default3({ message: "Please provide a new path:", default: targetPath });
108279
- targetPath = inputPath.trim();
108280
- }
108281
- };
108282
- var createCommand2 = new Command("create").description("Create a new project").argument("[name]", "Project name").action(async (name18, _options, command2) => {
108283
- const cmdOptions = command2.parent?.opts() ?? {};
108284
- const { providerConfig, maxMessageCount, verbose, budget } = parseOptions(cmdOptions);
108285
- let { provider: maybeProvider, model, apiKey } = providerConfig.getConfigForAgent("architect") ?? {};
108286
- if (!maybeProvider) {
108287
- const newConfig = await configPrompt({});
108288
- maybeProvider = newConfig.provider;
108289
- model = newConfig.model;
108290
- apiKey = newConfig.apiKey;
108291
- }
108292
- const provider3 = maybeProvider;
108293
- let projectName = name18;
108294
- if (!projectName) {
108295
- const inputName = await esm_default3({ message: "What would you like to name your project?" });
108296
- projectName = inputName.trim();
108297
- }
108298
- const targetPath = await askForPath(projectName);
108299
- try {
108300
- await mkdir2(targetPath, { recursive: true });
108301
- } catch (error43) {
108302
- console.error(`Failed to create directory: ${targetPath}`, error43);
108303
- process.exit(1);
108304
- }
108305
- process.chdir(targetPath);
108306
- const runner = new Runner({
108307
- providerConfig: new ApiProviderConfig({ defaultProvider: provider3, defaultModel: model, providers: { [provider3]: { apiKey } } }),
108308
- config: {},
108309
- maxMessageCount,
108310
- budget,
108311
- interactive: true,
108312
- verbose,
108313
- availableAgents: [architectAgentInfo, coderAgentInfo]
107511
+ if (!commandConfig) {
107512
+ throw new Error("Internal error: command configuration is missing for a non-init command.");
107513
+ }
107514
+ return getModel(commandConfig);
108314
107515
  });
108315
- await createNewProject(runner.multiAgent, projectName);
108316
- });
108317
-
108318
- // src/commands/init.ts
108319
- import { existsSync as existsSync4, mkdirSync, readFileSync as readFileSync2, writeFileSync } from "node:fs";
108320
- import { dirname as dirname2 } from "node:path";
108321
- var import_lodash8 = __toESM(require_lodash(), 1);
108322
-
108323
- // ../../node_modules/yaml/dist/index.js
108324
- var composer2 = require_composer2();
108325
- var Document2 = require_Document2();
108326
- var Schema2 = require_Schema2();
108327
- var errors5 = require_errors2();
108328
- var Alias2 = require_Alias2();
108329
- var identity2 = require_identity2();
108330
- var Pair2 = require_Pair2();
108331
- var Scalar2 = require_Scalar2();
108332
- var YAMLMap2 = require_YAMLMap2();
108333
- var YAMLSeq2 = require_YAMLSeq2();
108334
- var cst2 = require_cst2();
108335
- var lexer2 = require_lexer2();
108336
- var lineCounter2 = require_line_counter2();
108337
- var parser2 = require_parser2();
108338
- var publicApi2 = require_public_api3();
108339
- var visit2 = require_visit2();
108340
- var $Composer2 = composer2.Composer;
108341
- var $Document2 = Document2.Document;
108342
- var $Schema2 = Schema2.Schema;
108343
- var $YAMLError2 = errors5.YAMLError;
108344
- var $YAMLParseError2 = errors5.YAMLParseError;
108345
- var $YAMLWarning2 = errors5.YAMLWarning;
108346
- var $Alias2 = Alias2.Alias;
108347
- var $isAlias2 = identity2.isAlias;
108348
- var $isCollection2 = identity2.isCollection;
108349
- var $isDocument2 = identity2.isDocument;
108350
- var $isMap2 = identity2.isMap;
108351
- var $isNode2 = identity2.isNode;
108352
- var $isPair2 = identity2.isPair;
108353
- var $isScalar2 = identity2.isScalar;
108354
- var $isSeq2 = identity2.isSeq;
108355
- var $Pair2 = Pair2.Pair;
108356
- var $Scalar2 = Scalar2.Scalar;
108357
- var $YAMLMap2 = YAMLMap2.YAMLMap;
108358
- var $YAMLSeq2 = YAMLSeq2.YAMLSeq;
108359
- var $Lexer2 = lexer2.Lexer;
108360
- var $LineCounter2 = lineCounter2.LineCounter;
108361
- var $Parser2 = parser2.Parser;
108362
- var $parse2 = publicApi2.parse;
108363
- var $parseAllDocuments2 = publicApi2.parseAllDocuments;
108364
- var $parseDocument2 = publicApi2.parseDocument;
108365
- var $stringify2 = publicApi2.stringify;
108366
- var $visit2 = visit2.visit;
108367
- var $visitAsync2 = visit2.visitAsync;
108368
-
108369
- // src/commands/init.ts
108370
- var initCommand = new Command("init").description("Initialize polkacodes configuration").option("-g, --global", "Use global config");
108371
- initCommand.action(async (options, command2) => {
108372
- const cmdOptions = command2.parent?.opts() ?? {};
108373
- parseOptions(cmdOptions);
108374
- cmdOptions.baseDir = undefined;
108375
- const globalConfigPath = getGlobalConfigPath();
108376
- let gloabl = options.global;
108377
- let configPath = gloabl ? globalConfigPath : localConfigFileName;
107516
+ const coreStepHandler = combineHandlers(customStepSpecHandler, sequentialStepSpecHandler, agentStepHandler);
107517
+ const spinner = ora({
107518
+ text: "Gathering information...",
107519
+ stream: process.stderr
107520
+ }).start();
107521
+ const usage = new UsageMeter(import_lodash7.merge(prices_default, config4.prices ?? {}), { maxMessages: config4.maxMessageCount, maxCost: config4.budget });
107522
+ const customConsole = json2 ? new Console(process.stderr, process.stderr) : console;
107523
+ const onEvent = verbose > 0 ? printEvent(verbose, usage, customConsole) : undefined;
107524
+ const toolProviderOptions = {
107525
+ excludeFiles: config4.excludeFiles
107526
+ };
107527
+ const toolProvider = getProvider(toolProviderOptions);
107528
+ const agentConfig = commandName === "init" ? undefined : providerConfig.getConfigForCommand(commandName);
107529
+ const context = {
107530
+ ui: { spinner },
107531
+ cmdOptions: parentOptions,
107532
+ provider: toolProvider,
107533
+ parameters: {
107534
+ toolFormat: config4.toolFormat,
107535
+ os: os5.platform(),
107536
+ policies: [EnableCachePolicy],
107537
+ modelParameters: agentConfig?.parameters,
107538
+ scripts: config4.scripts,
107539
+ retryCount: config4.retryCount,
107540
+ requestTimeoutSeconds: config4.requestTimeoutSeconds,
107541
+ usageMeter: usage
107542
+ },
107543
+ verbose,
107544
+ agentCallback: onEvent,
107545
+ logger: customConsole
107546
+ };
108378
107547
  try {
108379
- if (existsSync4(configPath)) {
108380
- const proceed = await esm_default2({
108381
- message: `Found existing config at ${configPath}. Do you want to proceed? This will overwrite the existing config.`,
108382
- default: false
108383
- });
108384
- if (!proceed) {
108385
- console.log("Cancelled");
108386
- return;
108387
- }
108388
- } else {
108389
- if (!global) {
108390
- const isGlobal = await esm_default5({
108391
- message: "No config file found. Do you want to create one?",
108392
- choices: [
108393
- {
108394
- name: `Create a global config at ${globalConfigPath}`,
108395
- value: true
108396
- },
108397
- {
108398
- name: `Create a local config at ${configPath}`,
108399
- value: false
108400
- }
108401
- ]
108402
- });
108403
- if (isGlobal) {
108404
- gloabl = true;
108405
- configPath = globalConfigPath;
108406
- }
108407
- }
108408
- }
108409
- console.log(`Config file path: ${configPath}`);
108410
- let existingConfig = {};
108411
- try {
108412
- existingConfig = loadConfigAtPath(configPath) ?? {};
108413
- } catch (error43) {
108414
- if (error43 instanceof ZodError) {
108415
- console.error(`Unable to parse config file: ${configPath}`, error43);
108416
- process.exit(1);
108417
- }
108418
- }
108419
- const { providerConfig, verbose, maxMessageCount, budget } = parseOptions(cmdOptions);
108420
- let { provider: maybeProvider, model, apiKey, parameters } = providerConfig.getConfigForCommand("init") ?? {};
108421
- let newConfig;
108422
- if (!maybeProvider) {
108423
- newConfig = await configPrompt({});
108424
- maybeProvider = newConfig.provider;
108425
- model = newConfig.model;
108426
- apiKey = newConfig.apiKey;
108427
- }
108428
- const provider3 = maybeProvider;
108429
- if (newConfig?.apiKey && !gloabl) {
108430
- const option = await esm_default5({
108431
- message: "It is not recommended to store API keys in the local config file. How would you like to proceed?",
108432
- choices: [
108433
- {
108434
- name: "Save API key in the local config file",
108435
- value: 1
108436
- },
108437
- {
108438
- name: "Save API key in the global config file",
108439
- value: 2
108440
- },
108441
- {
108442
- name: "Save API key to .env file",
108443
- value: 3
108444
- }
108445
- ]
108446
- });
108447
- switch (option) {
108448
- case 1:
108449
- break;
108450
- case 2: {
108451
- const globalConfig2 = loadConfigAtPath(globalConfigPath) ?? {};
108452
- import_lodash8.set(globalConfig2, ["providers", newConfig.provider, "apiKey"], newConfig.apiKey);
108453
- mkdirSync(dirname2(globalConfigPath), { recursive: true });
108454
- writeFileSync(globalConfigPath, $stringify2(globalConfig2));
108455
- console.log(`API key saved to global config file: ${globalConfigPath}`);
108456
- newConfig.apiKey = undefined;
108457
- break;
108458
- }
108459
- case 3: {
108460
- let envFileContent;
108461
- if (existsSync4(".env")) {
108462
- envFileContent = readFileSync2(".env", "utf8");
108463
- envFileContent += `
108464
- ${newConfig.provider.toUpperCase()}_API_KEY=${newConfig.apiKey}`;
108465
- } else {
108466
- envFileContent = `${newConfig.provider.toUpperCase()}_API_KEY=${newConfig.apiKey}`;
108467
- }
108468
- writeFileSync(".env", envFileContent);
108469
- console.log("API key saved to .env file");
108470
- newConfig.apiKey = undefined;
108471
- break;
108472
- }
108473
- }
108474
- }
108475
- const shouldAnalyze = !gloabl && await esm_default2({
108476
- message: "Would you like to analyze the project to generate recommended configuration?",
108477
- default: true
108478
- });
108479
- let generatedConfig = {};
108480
- if (shouldAnalyze) {
108481
- const runner = new Runner({
108482
- providerConfig: new ApiProviderConfig({
108483
- defaultProvider: provider3,
108484
- defaultModel: model,
108485
- defaultParameters: parameters,
108486
- providers: { [provider3]: { apiKey } }
108487
- }),
108488
- config: {},
108489
- maxMessageCount,
108490
- budget,
108491
- interactive: true,
108492
- verbose,
108493
- availableAgents: [analyzerAgentInfo]
108494
- });
108495
- console.log("Analyzing project files...");
108496
- const response = await generateProjectConfig(runner.multiAgent, undefined);
108497
- generatedConfig = response ? $parse2(response) : {};
108498
- }
108499
- const finalConfig = {
108500
- ...existingConfig ?? {},
108501
- ...generatedConfig
108502
- };
108503
- if (newConfig) {
108504
- finalConfig.defaultProvider = newConfig.provider;
108505
- finalConfig.defaultModel = newConfig.model;
108506
- if (newConfig.apiKey) {
108507
- import_lodash8.set(finalConfig, ["providers", newConfig.provider, "apiKey"], newConfig.apiKey);
107548
+ const result = await run(workflow3, context, coreStepHandler, workflowInput);
107549
+ if (result.type === "success") {
107550
+ await handleSuccess(result, command2, usage);
107551
+ } else if (result.type === "error") {
107552
+ if (result.error?.message === "User cancelled") {
107553
+ spinner.stop();
107554
+ process.exit(130);
108508
107555
  }
108509
- }
108510
- mkdirSync(dirname2(configPath), { recursive: true });
108511
- writeFileSync(configPath, $stringify2(finalConfig));
108512
- console.log(`Configuration saved to ${configPath}`);
108513
- } catch (error43) {
108514
- console.error("Failed to generate configuration:", error43);
108515
- process.exit(1);
108516
- }
108517
- });
108518
-
108519
- // src/commands/pr.ts
108520
- import { execSync as execSync2, spawnSync as spawnSync3 } from "node:child_process";
108521
- var import_lodash9 = __toESM(require_lodash(), 1);
108522
- var prCommand = new Command("pr").description("Create a GitHub pull request").argument("[message]", "Optional context for the commit message generation").action(async (message, _options, command2) => {
108523
- const options = command2.parent?.opts() ?? {};
108524
- const { providerConfig, config: config4 } = parseOptions(options);
108525
- const commandConfig = providerConfig.getConfigForCommand("pr");
108526
- if (!commandConfig || !commandConfig.provider || !commandConfig.model) {
108527
- console.error('Error: No provider specified. Please run "polka config" to configure your AI provider.');
108528
- process.exit(1);
108529
- }
108530
- const spinner = ora("Gathering information...").start();
108531
- console.log("Provider:", commandConfig.provider);
108532
- console.log("Model:", commandConfig.model);
108533
- try {
108534
- execSync2("gh --version", { stdio: "ignore" });
108535
- } catch {
108536
- console.error("Error: GitHub CLI (gh) is not installed. Please install it from https://cli.github.com/");
108537
- process.exit(1);
108538
- }
108539
- try {
108540
- const branchName = execSync2("git rev-parse --abbrev-ref HEAD", { encoding: "utf-8" }).trim();
108541
- const defaultBranchNames = ["master", "main", "develop"];
108542
- let defaultBranch;
108543
- for (const branchName2 of defaultBranchNames) {
108544
- if (execSync2(`git branch --list ${branchName2}`, { encoding: "utf-8" }).includes(branchName2)) {
108545
- defaultBranch = branchName2;
108546
- break;
107556
+ const errorMessage = result.error?.message ?? "An unknown error occurred";
107557
+ spinner.fail(`Error during ${commandName}: ${errorMessage}`);
107558
+ if (result.error) {
107559
+ console.error(result.error);
108547
107560
  }
108548
- }
108549
- if (!defaultBranch) {
108550
- const originInfo = execSync2("git remote show origin", { encoding: "utf-8" });
108551
- defaultBranch = originInfo.match(/HEAD branch: (.*)/)?.[1];
108552
- }
108553
- if (!defaultBranch) {
108554
- console.error("Error: Could not determine default branch name.");
108555
107561
  process.exit(1);
108556
107562
  }
108557
- const commits = execSync2(`git --no-pager log --oneline --no-color --no-merges --no-decorate ${defaultBranch}..HEAD`, {
108558
- encoding: "utf-8"
108559
- });
108560
- const diff = execSync2(`git diff --cached -U50 ${defaultBranch}`, { encoding: "utf-8" });
108561
- const usage = new UsageMeter(import_lodash9.merge(prices_default, config4.prices ?? {}));
108562
- const ai = getModel(commandConfig);
108563
- spinner.text = "Generating pull request details...";
108564
- const resp = await generateGithubPullRequestDetails(ai, {
108565
- commitDiff: diff,
108566
- commitMessages: commits,
108567
- branchName,
108568
- context: message
108569
- }, usage);
108570
- usage.printUsage();
108571
- spinner.succeed("Pull request details generated");
108572
- const title = resp.title.trim();
108573
- const description = resp.description.trim();
108574
- console.log("Title:", title);
108575
- console.log(description);
108576
- await new Promise((resolve7) => setTimeout(resolve7, 10));
108577
- spawnSync3("gh", ["pr", "create", "--title", title, "--body", description], {
108578
- stdio: "inherit"
108579
- });
108580
- usage.printUsage();
108581
107563
  } catch (error43) {
108582
- console.error("Error creating pull request:", error43);
107564
+ const errorMessage = error43 instanceof Error ? error43.message : String(error43);
107565
+ spinner.fail(`Error during ${commandName}: ${errorMessage}`);
107566
+ console.error(error43);
108583
107567
  process.exit(1);
107568
+ } finally {
107569
+ if (!json2 && !suppressUsagePrint) {
107570
+ usage.printUsage();
107571
+ }
108584
107572
  }
108585
- });
108586
-
108587
- // src/commands/review.ts
108588
- import { Console } from "node:console";
108589
- var import_lodash10 = __toESM(require_lodash(), 1);
107573
+ }
108590
107574
 
108591
- // src/workflows/review.workflow.ts
108592
- import { execSync as execSync3 } from "node:child_process";
107575
+ // src/workflows/commit.workflow.ts
107576
+ import { execSync as execSync2 } from "node:child_process";
108593
107577
 
108594
107578
  // src/tools/utils/diffLineNumbers.ts
108595
107579
  function parseHunkHeader(header) {
@@ -108753,7 +107737,94 @@ var gitDiff_default = {
108753
107737
  handler: handler15,
108754
107738
  isAvailable: isAvailable15
108755
107739
  };
108756
- // src/workflows/review.workflow.ts
107740
+ // src/workflows/workflow.utils.ts
107741
+ import { execSync } from "node:child_process";
107742
+ function parseGitDiffNameStatus(diffOutput) {
107743
+ const lines = diffOutput.split(`
107744
+ `).filter((line) => line.trim());
107745
+ return lines.map((line) => {
107746
+ const [status, ...pathParts] = line.split("\t");
107747
+ const path = pathParts.join("\t");
107748
+ let statusDescription;
107749
+ switch (status[0]) {
107750
+ case "A":
107751
+ statusDescription = "Added";
107752
+ break;
107753
+ case "M":
107754
+ statusDescription = "Modified";
107755
+ break;
107756
+ case "D":
107757
+ statusDescription = "Deleted";
107758
+ break;
107759
+ case "R":
107760
+ statusDescription = "Renamed";
107761
+ break;
107762
+ case "C":
107763
+ statusDescription = "Copied";
107764
+ break;
107765
+ case "T":
107766
+ statusDescription = "Type changed";
107767
+ break;
107768
+ default:
107769
+ statusDescription = "Unknown";
107770
+ }
107771
+ return { path, status: statusDescription };
107772
+ });
107773
+ }
107774
+ function printChangedFiles(title, changedFiles, spinner, logger) {
107775
+ if (changedFiles.length === 0) {
107776
+ return;
107777
+ }
107778
+ spinner.stop();
107779
+ logger.log(title);
107780
+ for (const file2 of changedFiles) {
107781
+ logger.log(`- ${file2.status}: ${file2.path}`);
107782
+ }
107783
+ spinner.start();
107784
+ }
107785
+ function checkGhInstalled() {
107786
+ try {
107787
+ execSync("gh --version", { stdio: "ignore" });
107788
+ } catch {
107789
+ throw new Error("GitHub CLI (gh) is not installed. Please install it from https://cli.github.com/");
107790
+ }
107791
+ }
107792
+ function getDefaultBranch() {
107793
+ const defaultBranches = ["master", "main", "develop"];
107794
+ for (const branch of defaultBranches) {
107795
+ try {
107796
+ execSync(`git show-ref --verify --quiet refs/heads/${branch}`);
107797
+ return branch;
107798
+ } catch {}
107799
+ }
107800
+ try {
107801
+ checkGhInstalled();
107802
+ const branch = execSync("gh repo view --json defaultBranchRef --jq .defaultBranchRef.name", {
107803
+ encoding: "utf-8"
107804
+ }).trim();
107805
+ if (branch) {
107806
+ return branch;
107807
+ }
107808
+ } catch {}
107809
+ try {
107810
+ const output = execSync("git remote show origin", { encoding: "utf-8" });
107811
+ const match = output.match(/HEAD branch: (.*)/);
107812
+ if (match?.[1]) {
107813
+ return match[1];
107814
+ }
107815
+ } catch {}
107816
+ return;
107817
+ }
107818
+ var unquotePath = (path) => {
107819
+ if (path.startsWith('"') && path.endsWith('"')) {
107820
+ try {
107821
+ return JSON.parse(path);
107822
+ } catch {
107823
+ return path.substring(1, path.length - 1);
107824
+ }
107825
+ }
107826
+ return path;
107827
+ };
108757
107828
  function parseGitStatus(statusOutput) {
108758
107829
  const statusLines = statusOutput.split(`
108759
107830
  `).filter((line) => line);
@@ -108761,7 +107832,7 @@ function parseGitStatus(statusOutput) {
108761
107832
  for (const line of statusLines) {
108762
107833
  const indexStatus = line[0];
108763
107834
  const workingTreeStatus = line[1];
108764
- const filepath = line.slice(3);
107835
+ const path = line.length > 3 ? unquotePath(line.slice(3)) : line;
108765
107836
  const statuses = [];
108766
107837
  if (indexStatus !== " " && indexStatus !== "?") {
108767
107838
  switch (indexStatus) {
@@ -108800,54 +107871,424 @@ function parseGitStatus(statusOutput) {
108800
107871
  }
108801
107872
  }
108802
107873
  if (statuses.length > 0) {
108803
- files.push({ path: filepath, status: statuses.join(", ") });
107874
+ files.push({ path, status: statuses.join(", ") });
108804
107875
  }
108805
107876
  }
108806
107877
  return files;
108807
107878
  }
108808
- function parseGitDiffNameStatus(diffOutput) {
108809
- const lines = diffOutput.split(`
108810
- `).filter((line) => line.trim());
108811
- return lines.map((line) => {
108812
- const [status, ...pathParts] = line.split("\t");
108813
- const path = pathParts.join("\t");
108814
- let statusDescription;
108815
- switch (status[0]) {
108816
- case "A":
108817
- statusDescription = "Added";
108818
- break;
108819
- case "M":
108820
- statusDescription = "Modified";
108821
- break;
108822
- case "D":
108823
- statusDescription = "Deleted";
108824
- break;
108825
- case "R":
108826
- statusDescription = "Renamed";
108827
- break;
108828
- case "C":
108829
- statusDescription = "Copied";
108830
- break;
108831
- case "T":
108832
- statusDescription = "Type changed";
108833
- break;
108834
- default:
108835
- statusDescription = "Unknown";
107879
+
107880
+ // src/workflows/commit.workflow.ts
107881
+ var ensureStaged = {
107882
+ id: "ensure-staged",
107883
+ type: "custom",
107884
+ run: async (input, context) => {
107885
+ const { all, context: userContext } = input;
107886
+ const logger = context.logger ?? console;
107887
+ const {
107888
+ ui: { spinner }
107889
+ } = context;
107890
+ const status = execSync2("git status --porcelain=v1", { encoding: "utf-8" });
107891
+ const statusLines = status.split(`
107892
+ `).filter(Boolean);
107893
+ const hasStaged = statusLines.some((line) => line[0] !== " " && line[0] !== "?");
107894
+ if (!hasStaged) {
107895
+ if (all) {
107896
+ execSync2("git add .", { stdio: "ignore" });
107897
+ } else {
107898
+ spinner.stop();
107899
+ let addAll = false;
107900
+ try {
107901
+ addAll = await esm_default2({ message: "No staged files found. Stage all files?" });
107902
+ } catch (_err) {
107903
+ return { type: "error", error: new Error("User cancelled") };
107904
+ }
107905
+ if (!addAll) {
107906
+ return { type: "error", error: new Error("No files to commit") };
107907
+ }
107908
+ spinner.start();
107909
+ execSync2("git add .", { stdio: "ignore" });
107910
+ }
108836
107911
  }
108837
- return { path, status: statusDescription };
108838
- });
107912
+ let changedFiles = [];
107913
+ try {
107914
+ const diffNameStatus = execSync2("git diff --name-status --no-color --staged", { encoding: "utf-8" });
107915
+ changedFiles = parseGitDiffNameStatus(diffNameStatus);
107916
+ } catch {}
107917
+ printChangedFiles("Staged files:", changedFiles, spinner, logger);
107918
+ spinner.text = "Generating commit message...";
107919
+ return { type: "success", output: { context: userContext, changedFiles } };
107920
+ }
107921
+ };
107922
+ var COMMIT_MESSAGE_PROMPT = `
107923
+ You are an expert at writing git commit messages.
107924
+ Based on the provided list of staged files in <file_status> and optional user context in <tool_input_context>, generate a concise and descriptive commit message.
107925
+
107926
+ Use the 'git_diff' tool with 'staged: true' to get the content of the changes.
107927
+
107928
+ Follow the conventional commit format.
107929
+
107930
+ Respond with a JSON object containing the commit message.
107931
+ Example format:
107932
+ \`\`\`json
107933
+ {
107934
+ "commitMessage": "feat: add new feature\\n\\ndescribe the new feature in more detail"
108839
107935
  }
108840
- function printChangedFiles(changedFiles, spinner, logger) {
108841
- if (changedFiles.length === 0) {
108842
- return;
107936
+ \`\`\`
107937
+ `;
107938
+ var commitMessageSchema = exports_external.object({ commitMessage: exports_external.string() });
107939
+ var handleCommitResult = {
107940
+ id: "handle-commit-message",
107941
+ type: "custom",
107942
+ run: async (input, context) => {
107943
+ const logger = context.logger ?? console;
107944
+ const {
107945
+ ui: { spinner }
107946
+ } = context;
107947
+ spinner.succeed("Commit message generated");
107948
+ logger.log(`
107949
+ Commit message:
107950
+ ${input.commitMessage}`);
107951
+ return { type: "success", output: { commitMessage: input.commitMessage } };
108843
107952
  }
108844
- spinner.stop();
108845
- logger.log("Changed files:");
108846
- for (const file2 of changedFiles) {
108847
- logger.log(`- ${file2.status}: ${file2.path}`);
107953
+ };
107954
+ var commitWorkflow = {
107955
+ name: "Generate Commit Message",
107956
+ description: "Generate a Git commit message based on staged changes",
107957
+ step: builder().custom(ensureStaged).agent("generate-commit-message", {
107958
+ agent: "analyzer",
107959
+ tools: [gitDiff_default],
107960
+ messages: [
107961
+ COMMIT_MESSAGE_PROMPT,
107962
+ {
107963
+ type: "function",
107964
+ fn: (input) => {
107965
+ const fileList = input.changedFiles.map((file2) => `${file2.status}: ${file2.path}`).join(`
107966
+ `);
107967
+ let ret = `<file_status>
107968
+ ${fileList}
107969
+ </file_status>`;
107970
+ if (input.context) {
107971
+ ret += `
107972
+ <tool_input_context>
107973
+ ${input.context}
107974
+ </tool_input_context>`;
107975
+ }
107976
+ return ret;
107977
+ }
107978
+ }
107979
+ ],
107980
+ outputSchema: commitMessageSchema,
107981
+ parseOutput: parseJsonFromMarkdown
107982
+ }).custom(handleCommitResult).build()
107983
+ };
107984
+ // src/workflows/init.workflow.ts
107985
+ import { existsSync as existsSync3, mkdirSync, readFileSync as readFileSync2, writeFileSync } from "node:fs";
107986
+ import { dirname as dirname2 } from "node:path";
107987
+ var import_lodash8 = __toESM(require_lodash(), 1);
107988
+
107989
+ // ../../node_modules/yaml/dist/index.js
107990
+ var composer2 = require_composer2();
107991
+ var Document2 = require_Document2();
107992
+ var Schema2 = require_Schema2();
107993
+ var errors5 = require_errors2();
107994
+ var Alias2 = require_Alias2();
107995
+ var identity2 = require_identity2();
107996
+ var Pair2 = require_Pair2();
107997
+ var Scalar2 = require_Scalar2();
107998
+ var YAMLMap2 = require_YAMLMap2();
107999
+ var YAMLSeq2 = require_YAMLSeq2();
108000
+ var cst2 = require_cst2();
108001
+ var lexer2 = require_lexer2();
108002
+ var lineCounter2 = require_line_counter2();
108003
+ var parser2 = require_parser2();
108004
+ var publicApi2 = require_public_api3();
108005
+ var visit2 = require_visit2();
108006
+ var $Composer2 = composer2.Composer;
108007
+ var $Document2 = Document2.Document;
108008
+ var $Schema2 = Schema2.Schema;
108009
+ var $YAMLError2 = errors5.YAMLError;
108010
+ var $YAMLParseError2 = errors5.YAMLParseError;
108011
+ var $YAMLWarning2 = errors5.YAMLWarning;
108012
+ var $Alias2 = Alias2.Alias;
108013
+ var $isAlias2 = identity2.isAlias;
108014
+ var $isCollection2 = identity2.isCollection;
108015
+ var $isDocument2 = identity2.isDocument;
108016
+ var $isMap2 = identity2.isMap;
108017
+ var $isNode2 = identity2.isNode;
108018
+ var $isPair2 = identity2.isPair;
108019
+ var $isScalar2 = identity2.isScalar;
108020
+ var $isSeq2 = identity2.isSeq;
108021
+ var $Pair2 = Pair2.Pair;
108022
+ var $Scalar2 = Scalar2.Scalar;
108023
+ var $YAMLMap2 = YAMLMap2.YAMLMap;
108024
+ var $YAMLSeq2 = YAMLSeq2.YAMLSeq;
108025
+ var $Lexer2 = lexer2.Lexer;
108026
+ var $LineCounter2 = lineCounter2.LineCounter;
108027
+ var $Parser2 = parser2.Parser;
108028
+ var $parse2 = publicApi2.parse;
108029
+ var $parseAllDocuments2 = publicApi2.parseAllDocuments;
108030
+ var $parseDocument2 = publicApi2.parseDocument;
108031
+ var $stringify2 = publicApi2.stringify;
108032
+ var $visit2 = visit2.visit;
108033
+ var $visitAsync2 = visit2.visitAsync;
108034
+
108035
+ // src/workflows/init.workflow.ts
108036
+ var setupStep = {
108037
+ id: "setup",
108038
+ type: "custom",
108039
+ run: async (input, context) => {
108040
+ const { cmdOptions } = context;
108041
+ parseOptions(cmdOptions);
108042
+ cmdOptions.baseDir = undefined;
108043
+ const globalConfigPath = getGlobalConfigPath();
108044
+ let global3 = input.global ?? false;
108045
+ let configPath = global3 ? globalConfigPath : localConfigFileName;
108046
+ if (existsSync3(configPath)) {
108047
+ const proceed = await esm_default2({
108048
+ message: `Found existing config at ${configPath}. Do you want to proceed? This will overwrite the existing config.`,
108049
+ default: false
108050
+ });
108051
+ if (!proceed) {
108052
+ throw new Error("User cancelled");
108053
+ }
108054
+ } else {
108055
+ if (!input.global) {
108056
+ const isGlobal = await esm_default5({
108057
+ message: "No config file found. Do you want to create one?",
108058
+ choices: [
108059
+ { name: `Create a global config at ${globalConfigPath}`, value: true },
108060
+ { name: `Create a local config at ${configPath}`, value: false }
108061
+ ]
108062
+ });
108063
+ if (isGlobal) {
108064
+ global3 = true;
108065
+ configPath = globalConfigPath;
108066
+ }
108067
+ }
108068
+ }
108069
+ console.log(`Config file path: ${configPath}`);
108070
+ let existingConfig = {};
108071
+ try {
108072
+ existingConfig = loadConfigAtPath(configPath) ?? {};
108073
+ } catch (error43) {
108074
+ if (error43 instanceof ZodError) {
108075
+ console.error(`Unable to parse config file: ${configPath}`, error43);
108076
+ process.exit(1);
108077
+ }
108078
+ }
108079
+ return { type: "success", output: { global: global3, configPath, existingConfig, cmdOptions } };
108848
108080
  }
108849
- spinner.start();
108081
+ };
108082
+ var getProviderStep = {
108083
+ id: "get-provider",
108084
+ type: "custom",
108085
+ run: async (input) => {
108086
+ const { cmdOptions } = input;
108087
+ const { providerConfig } = parseOptions(cmdOptions);
108088
+ let { provider: maybeProvider, model, apiKey } = providerConfig.getConfigForCommand("init") ?? {};
108089
+ let newConfig;
108090
+ if (!maybeProvider) {
108091
+ newConfig = await configPrompt({});
108092
+ maybeProvider = newConfig.provider;
108093
+ model = newConfig.model;
108094
+ apiKey = newConfig.apiKey;
108095
+ }
108096
+ const provider3 = maybeProvider;
108097
+ return { type: "success", output: { ...input, newConfig, provider: provider3, model, apiKey } };
108098
+ }
108099
+ };
108100
+ var handleApiKeyStep = {
108101
+ id: "handle-api-key",
108102
+ type: "custom",
108103
+ run: async (input) => {
108104
+ const { newConfig, global: global3, provider: provider3 } = input;
108105
+ if (newConfig?.apiKey && !global3) {
108106
+ const option = await esm_default5({
108107
+ message: "It is not recommended to store API keys in the local config file. How would you like to proceed?",
108108
+ choices: [
108109
+ { name: "Save API key in the local config file", value: 1 },
108110
+ { name: "Save API key in the global config file", value: 2 },
108111
+ { name: "Save API key to .env file", value: 3 }
108112
+ ]
108113
+ });
108114
+ switch (option) {
108115
+ case 1:
108116
+ break;
108117
+ case 2: {
108118
+ const globalConfigPath = getGlobalConfigPath();
108119
+ const globalConfig2 = loadConfigAtPath(globalConfigPath) ?? {};
108120
+ import_lodash8.set(globalConfig2, ["providers", provider3, "apiKey"], newConfig.apiKey);
108121
+ mkdirSync(dirname2(globalConfigPath), { recursive: true });
108122
+ writeFileSync(globalConfigPath, $stringify2(globalConfig2));
108123
+ console.log(`API key saved to global config file: ${globalConfigPath}`);
108124
+ newConfig.apiKey = undefined;
108125
+ break;
108126
+ }
108127
+ case 3: {
108128
+ let envFileContent;
108129
+ if (existsSync3(".env")) {
108130
+ envFileContent = readFileSync2(".env", "utf8");
108131
+ envFileContent += `
108132
+ ${provider3.toUpperCase()}_API_KEY=${newConfig.apiKey}`;
108133
+ } else {
108134
+ envFileContent = `${provider3.toUpperCase()}_API_KEY=${newConfig.apiKey}`;
108135
+ }
108136
+ writeFileSync(".env", envFileContent);
108137
+ console.log("API key saved to .env file");
108138
+ newConfig.apiKey = undefined;
108139
+ break;
108140
+ }
108141
+ }
108142
+ }
108143
+ return { type: "success", output: input };
108144
+ }
108145
+ };
108146
+ var analyzeProjectStep = {
108147
+ id: "analyze-project",
108148
+ type: "custom",
108149
+ run: async (input) => {
108150
+ const { global: global3, cmdOptions, provider: provider3, model, apiKey } = input;
108151
+ let generatedConfig = {};
108152
+ const shouldAnalyze = !global3 && await esm_default2({
108153
+ message: "Would you like to analyze the project to generate recommended configuration?",
108154
+ default: true
108155
+ });
108156
+ if (shouldAnalyze) {
108157
+ const { providerConfig, config: config4, verbose, maxMessageCount, budget } = parseOptions(cmdOptions);
108158
+ const { parameters } = providerConfig.getConfigForCommand("init") ?? {};
108159
+ const runner = new Runner({
108160
+ providerConfig: new ApiProviderConfig({
108161
+ defaultProvider: provider3,
108162
+ defaultModel: model,
108163
+ defaultParameters: parameters,
108164
+ providers: { [provider3]: { apiKey } }
108165
+ }),
108166
+ config: config4,
108167
+ maxMessageCount,
108168
+ budget,
108169
+ interactive: true,
108170
+ verbose,
108171
+ availableAgents: [analyzerAgentInfo]
108172
+ });
108173
+ console.log("Analyzing project files...");
108174
+ const response = await generateProjectConfig(runner.multiAgent, undefined);
108175
+ generatedConfig = response ? $parse2(response) : {};
108176
+ }
108177
+ return { type: "success", output: { ...input, generatedConfig } };
108178
+ }
108179
+ };
108180
+ var saveConfigStep = {
108181
+ id: "save-config",
108182
+ type: "custom",
108183
+ run: async (input) => {
108184
+ const { existingConfig, generatedConfig, newConfig, configPath } = input;
108185
+ const finalConfig = {
108186
+ ...existingConfig ?? {},
108187
+ ...generatedConfig
108188
+ };
108189
+ if (newConfig) {
108190
+ finalConfig.defaultProvider = newConfig.provider;
108191
+ finalConfig.defaultModel = newConfig.model;
108192
+ if (newConfig.apiKey) {
108193
+ import_lodash8.set(finalConfig, ["providers", newConfig.provider, "apiKey"], newConfig.apiKey);
108194
+ }
108195
+ }
108196
+ mkdirSync(dirname2(configPath), { recursive: true });
108197
+ writeFileSync(configPath, $stringify2(finalConfig));
108198
+ console.log(`Configuration saved to ${configPath}`);
108199
+ return { type: "success", output: { configPath } };
108200
+ }
108201
+ };
108202
+ var initWorkflow = {
108203
+ name: "Initialize polkacodes",
108204
+ description: "Initialize polkacodes configuration.",
108205
+ step: builder().custom(setupStep).custom(getProviderStep).custom(handleApiKeyStep).custom(analyzeProjectStep).custom(saveConfigStep).build()
108206
+ };
108207
+ // src/workflows/pr.workflow.ts
108208
+ import { execSync as execSync3, spawnSync as spawnSync2 } from "node:child_process";
108209
+ var prDetailsSchema = exports_external.object({
108210
+ title: exports_external.string(),
108211
+ description: exports_external.string()
108212
+ });
108213
+ var GET_PR_DETAILS_PROMPT = `
108214
+ You are an expert at creating pull requests.
108215
+ Based on the provided branch name, commit messages, and diff, generate a title and description for the pull request.
108216
+
108217
+ Respond with a JSON object containing the title and description.
108218
+ Example format:
108219
+ \`\`\`json
108220
+ {
108221
+ "title": "feat: add new feature",
108222
+ "description": "This pull request adds a new feature that does...
108223
+
108224
+ ### Changes
108225
+ - ..."
108850
108226
  }
108227
+ \`\`\`
108228
+ `;
108229
+ var getGitInfo = {
108230
+ id: "get-git-info",
108231
+ type: "custom",
108232
+ run: async (input) => {
108233
+ checkGhInstalled();
108234
+ const branchName = execSync3("git rev-parse --abbrev-ref HEAD", { encoding: "utf-8" }).trim();
108235
+ const defaultBranch = getDefaultBranch();
108236
+ if (!defaultBranch) {
108237
+ throw new Error("Could not determine default branch name.");
108238
+ }
108239
+ const commits = execSync3(`git --no-pager log --oneline --no-color --no-merges --no-decorate ${defaultBranch}..HEAD`, {
108240
+ encoding: "utf-8"
108241
+ });
108242
+ const diff = execSync3(`git diff ${defaultBranch}..HEAD`, { encoding: "utf-8" });
108243
+ return { type: "success", output: { diff, commits, branchName, context: input.context } };
108244
+ }
108245
+ };
108246
+ var createPullRequest = {
108247
+ id: "create-pull-request",
108248
+ type: "custom",
108249
+ run: async (input, context) => {
108250
+ const { title, description } = input;
108251
+ const { ui } = context;
108252
+ if (ui.spinner.isSpinning) {
108253
+ ui.spinner.stop();
108254
+ }
108255
+ console.log("Title:", title);
108256
+ console.log(description);
108257
+ spawnSync2("gh", ["pr", "create", "--title", title, "--body", description], {
108258
+ stdio: "inherit"
108259
+ });
108260
+ return { type: "success", output: { title, description } };
108261
+ }
108262
+ };
108263
+ var prWorkflow = {
108264
+ name: "Create Pull Request",
108265
+ description: "Generate a pull request title and description and create the pull request.",
108266
+ step: builder().custom(getGitInfo).agent("generate-pr-details", {
108267
+ agent: "analyzer",
108268
+ messages: [
108269
+ GET_PR_DETAILS_PROMPT,
108270
+ {
108271
+ type: "function",
108272
+ fn: (input) => {
108273
+ const parts = [
108274
+ `<branch_name>${input.branchName}</branch_name>`,
108275
+ `<commit_messages>${input.commits}</commit_messages>`,
108276
+ `<diff>${input.diff}</diff>`
108277
+ ];
108278
+ if (input.context) {
108279
+ parts.push(`<user_context>${input.context}</user_context>`);
108280
+ }
108281
+ return parts.join(`
108282
+ `);
108283
+ }
108284
+ }
108285
+ ],
108286
+ outputSchema: prDetailsSchema,
108287
+ parseOutput: parseJsonFromMarkdown
108288
+ }).custom(createPullRequest).build()
108289
+ };
108290
+ // src/workflows/review.workflow.ts
108291
+ import { execSync as execSync4 } from "node:child_process";
108851
108292
  var specificReviewSchema = exports_external.object({
108852
108293
  file: exports_external.string(),
108853
108294
  lines: exports_external.string(),
@@ -108968,19 +108409,19 @@ var getChangeInfo = {
108968
108409
  }
108969
108410
  const prNumber = prNumberMatch[0];
108970
108411
  try {
108971
- execSync3("gh --version", { stdio: "ignore" });
108412
+ execSync4("gh --version", { stdio: "ignore" });
108972
108413
  } catch {
108973
108414
  throw new Error("Error: GitHub CLI (gh) is not installed. Please install it from https://cli.github.com/");
108974
108415
  }
108975
108416
  try {
108976
108417
  spinner.text = `Checking out PR #${prNumber}...`;
108977
- execSync3(`gh pr checkout ${prNumber}`, { stdio: "pipe" });
108418
+ execSync4(`gh pr checkout ${prNumber}`, { stdio: "pipe" });
108978
108419
  } catch (error43) {
108979
108420
  logger.error(error43);
108980
108421
  throw new Error(`Error checking out PR #${prNumber}. Make sure the PR number is correct and you have access to the repository.`);
108981
108422
  }
108982
108423
  spinner.text = "Fetching pull request details...";
108983
- const prDetails = JSON.parse(execSync3(`gh pr view ${prNumber} --json title,body,commits,baseRefName,baseRefOid`, {
108424
+ const prDetails = JSON.parse(execSync4(`gh pr view ${prNumber} --json title,body,commits,baseRefName,baseRefOid`, {
108984
108425
  encoding: "utf-8"
108985
108426
  }));
108986
108427
  const commitMessages = prDetails.commits.map((c) => c.messageBody).join(`
@@ -108989,14 +108430,14 @@ var getChangeInfo = {
108989
108430
  spinner.text = "Getting file changes...";
108990
108431
  let changedFiles = [];
108991
108432
  try {
108992
- const diffNameStatus = execSync3(`git diff --name-status --no-color ${prDetails.baseRefOid}...HEAD`, {
108433
+ const diffNameStatus = execSync4(`git diff --name-status --no-color ${prDetails.baseRefOid}...HEAD`, {
108993
108434
  encoding: "utf-8"
108994
108435
  });
108995
108436
  changedFiles = parseGitDiffNameStatus(diffNameStatus);
108996
108437
  } catch (_error) {
108997
108438
  logger.warn("Warning: Could not retrieve file changes list");
108998
108439
  }
108999
- printChangedFiles(changedFiles, spinner, logger);
108440
+ printChangedFiles("Changed files:", changedFiles, spinner, logger);
109000
108441
  changeInfo = {
109001
108442
  commitRange: `${prDetails.baseRefOid}...HEAD`,
109002
108443
  pullRequestTitle: prDetails.title,
@@ -109005,14 +108446,14 @@ var getChangeInfo = {
109005
108446
  changedFiles
109006
108447
  };
109007
108448
  } else {
109008
- const gitStatus = execSync3("git status --porcelain=v1", { encoding: "utf-8" });
108449
+ const gitStatus = execSync4("git status --porcelain=v1", { encoding: "utf-8" });
109009
108450
  const statusLines = gitStatus.split(`
109010
108451
  `).filter((line) => line);
109011
108452
  const hasLocalChanges = statusLines.length > 0;
109012
108453
  if (hasLocalChanges) {
109013
108454
  const hasStagedChanges = statusLines.some((line) => line[0] !== " " && line[0] !== "?");
109014
108455
  const changedFiles = parseGitStatus(gitStatus);
109015
- printChangedFiles(changedFiles, spinner, logger);
108456
+ printChangedFiles("Changed files:", changedFiles, spinner, logger);
109016
108457
  changeInfo = {
109017
108458
  staged: hasStagedChanges,
109018
108459
  changedFiles
@@ -109021,14 +108462,14 @@ var getChangeInfo = {
109021
108462
  spinner.text = "No local changes detected. Falling back to branch diff...";
109022
108463
  spinner.render();
109023
108464
  try {
109024
- execSync3("gh --version", { stdio: "ignore" });
108465
+ execSync4("gh --version", { stdio: "ignore" });
109025
108466
  } catch {
109026
108467
  throw new Error("Error: GitHub CLI (gh) is not installed, and there are no local changes to review. Please install it from https://cli.github.com/ to review branch changes.");
109027
108468
  }
109028
- const defaultBranch = execSync3("gh repo view --json defaultBranchRef --jq .defaultBranchRef.name", {
108469
+ const defaultBranch = execSync4("gh repo view --json defaultBranchRef --jq .defaultBranchRef.name", {
109029
108470
  encoding: "utf-8"
109030
108471
  }).trim();
109031
- const currentBranch = execSync3("git rev-parse --abbrev-ref HEAD", {
108472
+ const currentBranch = execSync4("git rev-parse --abbrev-ref HEAD", {
109032
108473
  encoding: "utf-8"
109033
108474
  }).trim();
109034
108475
  if (currentBranch === defaultBranch) {
@@ -109038,12 +108479,12 @@ var getChangeInfo = {
109038
108479
  spinner.text = "Getting file changes...";
109039
108480
  let branchChangedFiles = [];
109040
108481
  try {
109041
- const diffNameStatus = execSync3(`git diff --name-status --no-color ${defaultBranch}...${currentBranch}`, { encoding: "utf-8" });
108482
+ const diffNameStatus = execSync4(`git diff --name-status --no-color ${defaultBranch}...${currentBranch}`, { encoding: "utf-8" });
109042
108483
  branchChangedFiles = parseGitDiffNameStatus(diffNameStatus);
109043
108484
  } catch (_error) {
109044
108485
  logger.warn("Warning: Could not retrieve file changes list");
109045
108486
  }
109046
- printChangedFiles(branchChangedFiles, spinner, logger);
108487
+ printChangedFiles("Changed files:", branchChangedFiles, spinner, logger);
109047
108488
  changeInfo = {
109048
108489
  commitRange: `${defaultBranch}...${currentBranch}`,
109049
108490
  changedFiles: branchChangedFiles
@@ -109160,6 +108601,113 @@ var reviewWorkflow = {
109160
108601
  parseOutput: parseJsonFromMarkdown
109161
108602
  }).custom(handleResult3).build()
109162
108603
  };
108604
+ // src/commands/commit.ts
108605
+ var commitCommand = new Command("commit").description("Create a commit with AI-generated message").option("-a, --all", "Stage all files before committing").argument("[message]", "Optional context for the commit message generation").action(async (message, localOptions, command2) => {
108606
+ const input = { ...localOptions.all && { all: true }, ...message && { context: message } };
108607
+ const handleSuccess = async (result) => {
108608
+ if (result.type === "success") {
108609
+ const { commitMessage } = result.output;
108610
+ try {
108611
+ spawnSync3("git", ["commit", "-m", commitMessage], { stdio: "inherit" });
108612
+ } catch (error43) {
108613
+ console.error("Error: Commit failed", error43);
108614
+ process.exit(1);
108615
+ }
108616
+ }
108617
+ };
108618
+ await runWorkflowCommand("commit", commitWorkflow, command2, input, handleSuccess);
108619
+ });
108620
+
108621
+ // src/commands/create.ts
108622
+ import { existsSync as existsSync4 } from "node:fs";
108623
+ import { mkdir as mkdir2, stat } from "node:fs/promises";
108624
+ import { join as join3 } from "node:path";
108625
+ var askForPath = async (projectName) => {
108626
+ let targetPath = join3(process.cwd(), projectName);
108627
+ while (true) {
108628
+ const confirmPath = await esm_default2({
108629
+ message: `Do you want to create project at ${targetPath}?`,
108630
+ default: true
108631
+ });
108632
+ if (confirmPath) {
108633
+ if (existsSync4(targetPath)) {
108634
+ const targetStat = await stat(targetPath);
108635
+ if (targetStat.isDirectory()) {
108636
+ const confirmPath2 = await esm_default2({
108637
+ message: `Directory ${targetPath} already exists. Do you want to overwrite it?`,
108638
+ default: true
108639
+ });
108640
+ if (confirmPath2) {
108641
+ return targetPath;
108642
+ }
108643
+ } else {
108644
+ console.error("Target path is not a directory");
108645
+ }
108646
+ } else {
108647
+ return targetPath;
108648
+ }
108649
+ }
108650
+ const inputPath = await esm_default3({ message: "Please provide a new path:", default: targetPath });
108651
+ targetPath = inputPath.trim();
108652
+ }
108653
+ };
108654
+ var createCommand2 = new Command("create").description("Create a new project").argument("[name]", "Project name").action(async (name18, _options, command2) => {
108655
+ const cmdOptions = command2.parent?.opts() ?? {};
108656
+ const { providerConfig, maxMessageCount, verbose, budget } = parseOptions(cmdOptions);
108657
+ let { provider: maybeProvider, model, apiKey } = providerConfig.getConfigForAgent("architect") ?? {};
108658
+ if (!maybeProvider) {
108659
+ const newConfig = await configPrompt({});
108660
+ maybeProvider = newConfig.provider;
108661
+ model = newConfig.model;
108662
+ apiKey = newConfig.apiKey;
108663
+ }
108664
+ const provider3 = maybeProvider;
108665
+ let projectName = name18;
108666
+ if (!projectName) {
108667
+ const inputName = await esm_default3({ message: "What would you like to name your project?" });
108668
+ projectName = inputName.trim();
108669
+ }
108670
+ const targetPath = await askForPath(projectName);
108671
+ try {
108672
+ await mkdir2(targetPath, { recursive: true });
108673
+ } catch (error43) {
108674
+ console.error(`Failed to create directory: ${targetPath}`, error43);
108675
+ process.exit(1);
108676
+ }
108677
+ process.chdir(targetPath);
108678
+ const runner = new Runner({
108679
+ providerConfig: new ApiProviderConfig({ defaultProvider: provider3, defaultModel: model, providers: { [provider3]: { apiKey } } }),
108680
+ config: {},
108681
+ maxMessageCount,
108682
+ budget,
108683
+ interactive: true,
108684
+ verbose,
108685
+ availableAgents: [architectAgentInfo, coderAgentInfo]
108686
+ });
108687
+ await createNewProject(runner.multiAgent, projectName);
108688
+ });
108689
+
108690
+ // src/commands/init.ts
108691
+ var initCommand = new Command("init").description("Initialize polkacodes configuration").option("-g, --global", "Use global config").action(async (options, command2) => {
108692
+ await runWorkflowCommand("init", initWorkflow, command2, options, async (result, _command) => {
108693
+ if (result.type === "success") {
108694
+ console.log(`
108695
+ Configuration initialized successfully.`);
108696
+ }
108697
+ });
108698
+ });
108699
+
108700
+ // src/commands/pr.ts
108701
+ var prCommand = new Command("pr").description("Create a GitHub pull request").argument("[message]", "Optional context for the pull request generation").action(async (message, _options, command2) => {
108702
+ const input = { ...message && { context: message } };
108703
+ await runWorkflowCommand("pr", prWorkflow, command2, input, async (result, _command) => {
108704
+ if (result.type === "success") {
108705
+ console.log(`
108706
+ Pull request created successfully.`);
108707
+ }
108708
+ });
108709
+ });
108710
+
109163
108711
  // src/commands/task.ts
109164
108712
  import { readFile as readFile4 } from "node:fs/promises";
109165
108713
  var readStdin = async (timeoutMs = 30000) => {
@@ -109195,7 +108743,7 @@ var readStdin = async (timeoutMs = 30000) => {
109195
108743
  });
109196
108744
  });
109197
108745
  };
109198
- async function runTask(taskArg, _options, command2) {
108746
+ async function runTask(taskArg, _options, command2, opts = {}) {
109199
108747
  let task = taskArg;
109200
108748
  if (!task) {
109201
108749
  try {
@@ -109231,11 +108779,12 @@ async function runTask(taskArg, _options, command2) {
109231
108779
  budget,
109232
108780
  interactive: process.stdin.isTTY,
109233
108781
  verbose,
109234
- silent
108782
+ silent,
108783
+ externalUsageMeter: opts.externalUsageMeter
109235
108784
  });
109236
108785
  const sigintHandler = () => {
109237
108786
  runner.abort();
109238
- if (!silent) {
108787
+ if (!silent && !opts.suppressUsagePrint) {
109239
108788
  console.log();
109240
108789
  runner.printUsage();
109241
108790
  }
@@ -109277,79 +108826,37 @@ async function runTask(taskArg, _options, command2) {
109277
108826
  if (exitReason.type === "Exit" /* Exit */) {
109278
108827
  console.log(exitReason.message);
109279
108828
  }
109280
- } else {
108829
+ } else if (!opts.suppressUsagePrint) {
109281
108830
  runner.printUsage();
109282
108831
  }
109283
108832
  }
109284
108833
 
109285
108834
  // src/commands/review.ts
109286
108835
  var reviewCommand = new Command("review").description("Review a GitHub pull request or local changes").option("--pr <pr>", "The pull request number or URL to review").option("--json", "Output the review in JSON format", false).action(async (options, command2) => {
109287
- const parentOptions = command2.parent?.opts() ?? {};
109288
- const { providerConfig, config: config4, verbose } = parseOptions(parentOptions);
109289
- const commandConfig = providerConfig.getConfigForCommand("review");
109290
- if (!commandConfig || !commandConfig.provider || !commandConfig.model) {
109291
- console.error('Error: No provider specified. Please run "polka config" to configure your AI provider.');
109292
- process.exit(1);
109293
- }
109294
- if (!options.json) {
109295
- console.log("Provider:", commandConfig.provider);
109296
- console.log("Model:", commandConfig.model);
109297
- }
109298
- const agentStepHandler = makeAgentStepSpecHandler(async (_step, _context) => {
109299
- const commandConfig2 = providerConfig.getConfigForCommand("review");
109300
- if (!commandConfig2 || !commandConfig2.provider || !commandConfig2.model) {
109301
- throw new Error("No provider specified for the agent step.");
109302
- }
109303
- return getModel(commandConfig2);
109304
- });
109305
- const coreStepHandler = combineHandlers(customStepSpecHandler, sequentialStepSpecHandler, agentStepHandler);
109306
- const spinner = ora({
109307
- text: "Gathering information...",
109308
- stream: process.stderr
109309
- }).start();
109310
- const usage = new UsageMeter(import_lodash10.merge(prices_default, config4.prices ?? {}));
109311
- const customConsole = options.json ? new Console(process.stderr, process.stderr) : console;
109312
- const onEvent = parentOptions.verbose > 0 ? printEvent(parentOptions.verbose, usage, customConsole) : undefined;
109313
- const toolProviderOptions = {
109314
- excludeFiles: parentOptions.config.excludeFiles
109315
- };
109316
- const toolProvider = getProvider(toolProviderOptions);
109317
- const context = {
109318
- ui: { spinner },
109319
- provider: toolProvider,
109320
- parameters: parentOptions,
109321
- verbose,
109322
- agentCallback: onEvent,
109323
- logger: customConsole
109324
- };
109325
- const input = { json: options.json, ...options.pr && { pr: options.pr } };
109326
- try {
109327
- const result = await run(reviewWorkflow, context, coreStepHandler, input);
109328
- if (result.type === "success") {
109329
- if (result.output.shouldRunTask) {
109330
- const taskInstruction = `please address the review result:
108836
+ const { json: json2, pr: pr2 } = options;
108837
+ const input = { json: json2, ...pr2 && { pr: pr2 } };
108838
+ let _willRunTask = false;
108839
+ const handleSuccess = async (result, command3, usageMeter) => {
108840
+ if (result.type === "success" && result.output.shouldRunTask) {
108841
+ _willRunTask = true;
108842
+ if (!command3) {
108843
+ throw new Error("Command object not available in handleSuccess");
108844
+ }
108845
+ const taskInstruction = `please address the review result:
109331
108846
 
109332
108847
  ${result.output.formattedReview}`;
109333
- await runTask(taskInstruction, {}, command2);
109334
- }
109335
- } else if (result.type === "error") {
109336
- if (result.error) {
109337
- spinner.fail(`Error reviewing: ${result.error.message}`);
109338
- console.error(result.error);
109339
- } else {
109340
- spinner.fail("Error reviewing: An unknown error occurred");
109341
- }
109342
- process.exit(1);
109343
- }
109344
- } catch (error43) {
109345
- spinner.fail(`Error reviewing: ${error43 instanceof Error ? error43.message : String(error43)}`);
109346
- console.error(error43);
109347
- process.exit(1);
109348
- } finally {
109349
- if (!options.json) {
109350
- usage.printUsage();
108848
+ await runTask(taskInstruction, {}, command3, {
108849
+ externalUsageMeter: usageMeter,
108850
+ suppressUsagePrint: false
108851
+ });
108852
+ } else if (usageMeter && !json2) {
108853
+ usageMeter.printUsage();
109351
108854
  }
109352
- }
108855
+ };
108856
+ await runWorkflowCommand("review", reviewWorkflow, command2, input, handleSuccess, {
108857
+ json: json2,
108858
+ suppressUsagePrint: true
108859
+ });
109353
108860
  });
109354
108861
 
109355
108862
  // src/index.ts