@ai-hero/sandcastle 0.6.6 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.js CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { NodeContext_exports, withFriendlyErrors, NodeRuntime_exports } from './chunk-Q5W3WQVU.js';
4
- import { buildImage, removeImage } from './chunk-UPDEQ2U7.js';
5
- import { CommitPrototype, dual, GenericTag, fromIterable, failSync, map2, reduce, Effect_exports, Display, InitError, Layer_exports, ClackDisplay, decode, mapError, TreeFormatter, empty, none, flatMap3, catchAll, match, fail2 as fail2$1, map3, merge, some, right, left, isNonEmptyReadonlyArray, headNonEmpty, tailNonEmpty, isArray, identity, fromIterable2, fromIterable3, globalValue, contextWithEffect, getOrElse, getOption, appendAll, matchEffect, unify, catchSome, zipRight, matchLeft, defaultImageName, SANDBOX_REPO_DIR, FileSystem_exports, ConfigDirError, pipe, zipLeft, log, succeed, isOption, make4, update, repeatN, get2, getSomes, map, zipWith, make3, as, prepend, make, isEmpty, empty2, isEmptyReadonlyArray, of, catchTag, isTagged, die, isConfigError, isMissingDataOnly, filterMap, get, every, mapBoth, zip, forEach, _void, orElse, match2, join as join$1, isConfig, isObject, toStringUnknown, isSome, getOrThrow, FileSystem, try_, flatMap2, unsafeGet, drop, splitAt, tap, take, isQuitException, reduceRight, withMinimumLogLevel, error, PodmanError, mapInput, boolean, sort, contains, append, fromNullable, catchTags, when, set, pipeArguments, head, make10 as make10$1, suspend, get4, allocate, gen, updateAndGet, span, some2, sync, orElse2, has, filter, is, decodeUnknown, String$, fromString, make7 as make7$1, orElseFail, orDie, compose, NumberFromString, Int, Date$, findFirst, allLevels, updateEffect, flatten, fnUntraced, Terminal, QuitException, scoped, isNone, Literal, unlessEffect, asVoid, catchIf, runSync, of2, match3, filterOrDieMessage, Path, filter2, isEffect, taggedEnum, round, ensuring, cons, dieMessage, value, when2, orElse3, isNil, matchRight, symbol2, symbol, cached, findFirstIndex, flatMap, findLast, equals, combine, hash, string, string2, provide, provideServiceEffect, provideService, int } from './chunk-Z7O2WNRU.js';
3
+ import { NodeContext_exports, withFriendlyErrors, NodeRuntime_exports } from './chunk-52CIJF45.js';
4
+ import { buildImage, removeImage } from './chunk-NSFQW6ML.js';
5
+ import { CommitPrototype, dual, GenericTag, fromIterable, failSync, map2, reduce, Effect_exports, Display, InitError, Layer_exports, ClackDisplay, decode, mapError, TreeFormatter, empty, none, flatMap3, catchAll, match, fail2 as fail2$1, map3, merge, some, right, left, isNonEmptyReadonlyArray, headNonEmpty, tailNonEmpty, isArray, identity, fromIterable2, fromIterable3, globalValue, contextWithEffect, getOrElse, getOption, appendAll, matchEffect, unify, catchSome, zipRight, matchLeft, defaultImageName, Option_exports, SANDBOX_REPO_DIR, FileSystem_exports, ConfigDirError, pipe, zipLeft, log, succeed, isOption, make4, update, repeatN, get2, getSomes, map, zipWith, make3, as, prepend, make, isEmpty, empty2, isEmptyReadonlyArray, of, catchTag, isTagged, die, isConfigError, isMissingDataOnly, filterMap, get, every, mapBoth, zip, forEach, _void, orElse, match2, join as join$1, isConfig, isObject, toStringUnknown, isSome, getOrThrow, FileSystem, try_, flatMap2, unsafeGet, drop, splitAt, tap, take, isQuitException, reduceRight, withMinimumLogLevel, error, PodmanError, mapInput, boolean, sort, contains, append, fromNullable, catchTags, when, set, pipeArguments, head, make10 as make10$1, suspend, get4, allocate, gen, updateAndGet, span, some2, sync, orElse2, has, filter, is, decodeUnknown, String$, fromString, make7 as make7$1, orElseFail, orDie, compose, NumberFromString, Int, Date$, findFirst, allLevels, updateEffect, flatten, fnUntraced, Terminal, QuitException, scoped, isNone, Literal, unlessEffect, asVoid, catchIf, runSync, of2, match3, filterOrDieMessage, Path, filter2, isEffect, taggedEnum, round, ensuring, cons, dieMessage, value, when2, orElse3, isNil, matchRight, symbol2, symbol, cached, findFirstIndex, flatMap, findLast, equals, combine, hash, string, string2, provide, provideServiceEffect, provideService, int } from './chunk-5VM5QZ26.js';
6
6
  import './chunk-BIWNFKGV.js';
7
7
  import { __commonJS, __require, __toESM, __export } from './chunk-NGBM7T3E.js';
8
8
  import * as clack from '@clack/prompts';
@@ -18377,7 +18377,7 @@ ANTHROPIC_API_KEY=`,
18377
18377
  {
18378
18378
  name: "codex",
18379
18379
  label: "Codex",
18380
- defaultModel: "gpt-5.4-mini",
18380
+ defaultModel: "gpt-5.4",
18381
18381
  factoryImport: "codex",
18382
18382
  dockerfileTemplate: CODEX_DOCKERFILE,
18383
18383
  envExample: `# OpenAI API key
@@ -18403,7 +18403,7 @@ CURSOR_API_KEY=`,
18403
18403
  dockerfileTemplate: OPENCODE_DOCKERFILE,
18404
18404
  envExample: `# OpenCode API key
18405
18405
  OPENCODE_API_KEY=`,
18406
- setupCommand: `opencode -p "$(cat ${SETUP_ISSUE_TRACKER_PATH})"`
18406
+ setupCommand: `opencode --prompt "$(cat ${SETUP_ISSUE_TRACKER_PATH})"`
18407
18407
  },
18408
18408
  {
18409
18409
  name: "copilot",
@@ -18799,7 +18799,7 @@ var scaffold = (repoDir, options3) => Effect_exports.gen(function* () {
18799
18799
  }
18800
18800
  return { mainFilename };
18801
18801
  });
18802
- var VERSION = "0.6.6" ;
18802
+ var VERSION = "0.8.0" ;
18803
18803
 
18804
18804
  // src/cli.ts
18805
18805
  var imageNameOption = Options_exports.text("image-name").pipe(
@@ -18847,6 +18847,37 @@ var sandboxOption = Options_exports.text("sandbox").pipe(
18847
18847
  Options_exports.withDescription("Sandbox provider to use (e.g. docker, podman)"),
18848
18848
  Options_exports.optional
18849
18849
  );
18850
+ var issueTrackerOption = Options_exports.text("issue-tracker").pipe(
18851
+ Options_exports.withDescription(
18852
+ "Issue tracker to use (e.g. github-issues, beads, custom)"
18853
+ ),
18854
+ Options_exports.optional
18855
+ );
18856
+ var createLabelOption = Options_exports.choice("create-label", [
18857
+ "true",
18858
+ "false"
18859
+ ]).pipe(
18860
+ Options_exports.withDescription(
18861
+ 'Whether to create the "Sandcastle" GitHub label (only meaningful with --issue-tracker github-issues)'
18862
+ ),
18863
+ Options_exports.optional
18864
+ );
18865
+ var buildImageOption = Options_exports.choice("build-image", ["true", "false"]).pipe(
18866
+ Options_exports.withDescription(
18867
+ "Whether to build the sandbox image now (ignored when --issue-tracker custom is selected)"
18868
+ ),
18869
+ Options_exports.optional
18870
+ );
18871
+ var installTemplateDepsOption = Options_exports.choice("install-template-deps", [
18872
+ "true",
18873
+ "false"
18874
+ ]).pipe(
18875
+ Options_exports.withDescription(
18876
+ "Whether to install the template's host dependencies (e.g. zod for the planner templates)"
18877
+ ),
18878
+ Options_exports.optional
18879
+ );
18880
+ var choiceToTriBool = (opt) => opt._tag === "Some" ? Option_exports.some(opt.value === "true") : Option_exports.none();
18850
18881
  var initCommand = Command_exports.make(
18851
18882
  "init",
18852
18883
  {
@@ -18854,14 +18885,22 @@ var initCommand = Command_exports.make(
18854
18885
  template: templateOption,
18855
18886
  agent: agentOption,
18856
18887
  model: initModelOption,
18857
- sandbox: sandboxOption
18888
+ sandbox: sandboxOption,
18889
+ issueTracker: issueTrackerOption,
18890
+ createLabel: createLabelOption,
18891
+ buildImage: buildImageOption,
18892
+ installTemplateDeps: installTemplateDepsOption
18858
18893
  },
18859
18894
  ({
18860
18895
  imageName: imageNameFlag,
18861
18896
  template,
18862
18897
  agent: agentFlag,
18863
18898
  model: modelFlag,
18864
- sandbox: sandboxFlag
18899
+ sandbox: sandboxFlag,
18900
+ issueTracker: issueTrackerFlag,
18901
+ createLabel: createLabelFlag,
18902
+ buildImage: buildImageFlag,
18903
+ installTemplateDeps: installTemplateDepsFlag
18865
18904
  }) => Effect_exports.gen(function* () {
18866
18905
  const d = yield* Display;
18867
18906
  const cwd = process.cwd();
@@ -18889,6 +18928,46 @@ var initCommand = Command_exports.make(
18889
18928
  );
18890
18929
  }
18891
18930
  }
18931
+ if (issueTrackerFlag._tag === "Some") {
18932
+ const valid = getIssueTracker(issueTrackerFlag.value);
18933
+ if (!valid) {
18934
+ const names = listIssueTrackers().map((t) => t.name).join(", ");
18935
+ yield* Effect_exports.fail(
18936
+ new InitError({
18937
+ message: `Unknown issue tracker "${issueTrackerFlag.value}". Available: ${names}`
18938
+ })
18939
+ );
18940
+ }
18941
+ }
18942
+ const createLabelChoice = choiceToTriBool(createLabelFlag);
18943
+ const buildImageChoice = choiceToTriBool(buildImageFlag);
18944
+ const installTemplateDepsChoice = choiceToTriBool(
18945
+ installTemplateDepsFlag
18946
+ );
18947
+ const isInteractive = process.stdin.isTTY === true;
18948
+ const failIfNonInteractive = (flag) => Effect_exports.fail(
18949
+ new InitError({
18950
+ message: `${flag} is required in non-interactive mode (no TTY detected).`
18951
+ })
18952
+ );
18953
+ const resolveConfirmFlag = (params) => Effect_exports.gen(function* () {
18954
+ if (params.choice._tag === "Some") return params.choice.value;
18955
+ if (!isInteractive) {
18956
+ yield* failIfNonInteractive(params.flag);
18957
+ }
18958
+ const confirmed = yield* Effect_exports.promise(
18959
+ () => clack.confirm({
18960
+ message: params.promptMessage,
18961
+ initialValue: true
18962
+ })
18963
+ );
18964
+ if (clack.isCancel(confirmed)) {
18965
+ yield* Effect_exports.fail(
18966
+ new InitError({ message: params.cancelMessage })
18967
+ );
18968
+ }
18969
+ return confirmed === true;
18970
+ });
18892
18971
  const agents = listAgents();
18893
18972
  let selectedAgent;
18894
18973
  if (agentFlag._tag === "Some") {
@@ -18903,6 +18982,9 @@ var initCommand = Command_exports.make(
18903
18982
  }
18904
18983
  selectedAgent = entry;
18905
18984
  } else {
18985
+ if (!isInteractive) {
18986
+ yield* failIfNonInteractive("--agent");
18987
+ }
18906
18988
  const selected = yield* Effect_exports.promise(
18907
18989
  () => clack.select({
18908
18990
  message: "Select an agent:",
@@ -18927,6 +19009,9 @@ var initCommand = Command_exports.make(
18927
19009
  if (sandboxFlag._tag === "Some") {
18928
19010
  selectedSandboxProvider = getSandboxProvider(sandboxFlag.value);
18929
19011
  } else {
19012
+ if (!isInteractive) {
19013
+ yield* failIfNonInteractive("--sandbox");
19014
+ }
18930
19015
  const selected = yield* Effect_exports.promise(
18931
19016
  () => clack.select({
18932
19017
  message: "Select a sandbox provider:",
@@ -18947,7 +19032,12 @@ var initCommand = Command_exports.make(
18947
19032
  }
18948
19033
  const issueTrackers = listIssueTrackers();
18949
19034
  let selectedIssueTracker;
18950
- {
19035
+ if (issueTrackerFlag._tag === "Some") {
19036
+ selectedIssueTracker = getIssueTracker(issueTrackerFlag.value);
19037
+ } else {
19038
+ if (!isInteractive) {
19039
+ yield* failIfNonInteractive("--issue-tracker");
19040
+ }
18951
19041
  const selected = yield* Effect_exports.promise(
18952
19042
  () => clack.select({
18953
19043
  message: "Select an issue tracker:",
@@ -18971,6 +19061,9 @@ var initCommand = Command_exports.make(
18971
19061
  if (template._tag === "Some") {
18972
19062
  selectedTemplate = template.value;
18973
19063
  } else {
19064
+ if (!isInteractive) {
19065
+ yield* failIfNonInteractive("--template");
19066
+ }
18974
19067
  const selected = yield* Effect_exports.promise(
18975
19068
  () => clack.select({
18976
19069
  message: "Select a template:",
@@ -18991,13 +19084,13 @@ var initCommand = Command_exports.make(
18991
19084
  }
18992
19085
  let shouldCreateLabel = false;
18993
19086
  if (selectedIssueTracker.name === "github-issues") {
18994
- shouldCreateLabel = yield* Effect_exports.promise(
18995
- () => clack.confirm({
18996
- message: 'Create a "Sandcastle" GitHub label? (Templates filter issues by this label)',
18997
- initialValue: true
18998
- })
18999
- );
19000
- if (shouldCreateLabel === true) {
19087
+ shouldCreateLabel = yield* resolveConfirmFlag({
19088
+ choice: createLabelChoice,
19089
+ flag: "--create-label",
19090
+ promptMessage: 'Create a "Sandcastle" GitHub label? (Templates filter issues by this label)',
19091
+ cancelMessage: "Label selection cancelled."
19092
+ });
19093
+ if (shouldCreateLabel) {
19001
19094
  yield* Effect_exports.try({
19002
19095
  try: () => execSync(
19003
19096
  'gh label create "Sandcastle" --description "Issues for Sandcastle to work on" --color "F9A825" 2>/dev/null',
@@ -19013,7 +19106,7 @@ var initCommand = Command_exports.make(
19013
19106
  agent: selectedAgent,
19014
19107
  model: selectedModel,
19015
19108
  templateName: selectedTemplate,
19016
- createLabel: shouldCreateLabel === true,
19109
+ createLabel: shouldCreateLabel,
19017
19110
  issueTracker: selectedIssueTracker,
19018
19111
  sandboxProvider: selectedSandboxProvider
19019
19112
  }).pipe(
@@ -19029,13 +19122,13 @@ var initCommand = Command_exports.make(
19029
19122
  const alreadyInstalled = yield* hostHasDependency(cwd, "zod");
19030
19123
  if (!alreadyInstalled) {
19031
19124
  const installCmd = addDependencyCommand(packageManager, "zod");
19032
- const shouldInstall = yield* Effect_exports.promise(
19033
- () => clack.confirm({
19034
- message: `The ${selectedTemplate} template needs a schema validator. Install zod now (\`${installCmd}\`)?`,
19035
- initialValue: true
19036
- })
19037
- );
19038
- if (shouldInstall === true) {
19125
+ const shouldInstall = yield* resolveConfirmFlag({
19126
+ choice: installTemplateDepsChoice,
19127
+ flag: "--install-template-deps",
19128
+ promptMessage: `The ${selectedTemplate} template needs a schema validator. Install zod now (\`${installCmd}\`)?`,
19129
+ cancelMessage: "Install-template-deps selection cancelled."
19130
+ });
19131
+ if (shouldInstall) {
19039
19132
  const installed = yield* Effect_exports.sync(() => {
19040
19133
  try {
19041
19134
  execSync(installCmd, { cwd, stdio: "ignore" });
@@ -19058,13 +19151,13 @@ var initCommand = Command_exports.make(
19058
19151
  "success"
19059
19152
  );
19060
19153
  } else {
19061
- const shouldBuild = yield* Effect_exports.promise(
19062
- () => clack.confirm({
19063
- message: `Build the default ${providerLabel} image now?`,
19064
- initialValue: true
19065
- })
19066
- );
19067
- if (shouldBuild === true) {
19154
+ const shouldBuild = yield* resolveConfirmFlag({
19155
+ choice: buildImageChoice,
19156
+ flag: "--build-image",
19157
+ promptMessage: `Build the default ${providerLabel} image now?`,
19158
+ cancelMessage: "Build-image selection cancelled."
19159
+ });
19160
+ if (shouldBuild) {
19068
19161
  const containerfileDir = join(cwd, CONFIG_DIR);
19069
19162
  if (selectedSandboxProvider.name === "podman") {
19070
19163
  yield* d.spinner(