Compare commits

...

11 Commits

Author SHA1 Message Date
github-actions[bot]
827e0aeca7 chore(release): Update version to v1.4.343 2025-12-14 08:05:48 +00:00
Kayvan Sylvan
0a1e01c4ab Merge pull request #1829 from danielmiessler/dependabot/npm_and_yarn/web/npm_and_yarn-3c67cbb9cd
chore(deps): bump js-yaml from 4.1.0 to 4.1.1 in /web in the npm_and_yarn group across 1 directory
2025-12-14 00:03:09 -08:00
Changelog Bot
6003bb2c86 chore: incoming 1829 changelog entry 2025-12-13 23:52:18 -08:00
dependabot[bot]
bb896b1064 chore(deps): bump js-yaml
Bumps the npm_and_yarn group with 1 update in the /web directory: [js-yaml](https://github.com/nodeca/js-yaml).


Updates `js-yaml` from 4.1.0 to 4.1.1
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/4.1.0...4.1.1)

---
updated-dependencies:
- dependency-name: js-yaml
  dependency-version: 4.1.1
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-13 23:52:18 -08:00
github-actions[bot]
3d25fbc04c chore(release): Update version to v1.4.342 2025-12-13 08:11:50 +00:00
Kayvan Sylvan
4c822d2c59 Merge pull request #1866 from ksylvan/kayvan/errors-never-to-stdout
fix: write CLI and streaming errors to stderr
2025-12-13 00:09:09 -08:00
Changelog Bot
f1ffd6ee29 chore: incoming 1866 changelog entry 2025-12-13 00:07:08 -08:00
Kayvan Sylvan
deb59bdd21 fix: write CLI and streaming errors to stderr
## CHANGES
- Route CLI execution errors to standard error output
- Print Anthropic stream errors to stderr consistently
- Add os import to support stderr error writes
- Preserve help-output suppression and exit behavior
2025-12-13 00:02:44 -08:00
github-actions[bot]
2a1e8dcf12 chore(release): Update version to v1.4.341 2025-12-11 10:49:47 +00:00
Kayvan Sylvan
b6fd81dd16 Merge pull request #1860 from ksylvan/kayvan/fix-for-setup-reset-required-value-now-does-not-show-validation-error
fix: allow resetting required settings without validation errors
2025-12-11 18:47:16 +08:00
Kayvan Sylvan
5b723c9e92 fix: allow resetting required settings without validation errors
CHANGES
- update `Ask` to detect reset command and bypass validation
- refactor `OnAnswer` to support new `isReset` parameter logic
- invoke `ConfigureCustom` in `Setup` to avoid redundant re-validation
- add unit tests ensuring required fields can be reset
- add incoming 1860 changelog entry
2025-12-11 02:39:35 -08:00
9 changed files with 141 additions and 15 deletions

View File

@@ -1,5 +1,31 @@
# Changelog
## v1.4.343 (2025-12-14)
### PR [#1829](https://github.com/danielmiessler/Fabric/pull/1829) by [dependabo](https://github.com/apps/dependabot): chore(deps): bump js-yaml from 4.1.0 to 4.1.1 in /web in the npm_and_yarn group across 1 directory
- Updated js-yaml dependency from version 4.1.0 to 4.1.1 in the /web directory
## v1.4.342 (2025-12-13)
### PR [#1866](https://github.com/danielmiessler/Fabric/pull/1866) by [ksylvan](https://github.com/ksylvan): fix: write CLI and streaming errors to stderr
- Fix: write CLI and streaming errors to stderr
- Route CLI execution errors to standard error output
- Print Anthropic stream errors to stderr consistently
- Add os import to support stderr error writes
- Preserve help-output suppression and exit behavior
## v1.4.341 (2025-12-10)
### PR [#1860](https://github.com/danielmiessler/Fabric/pull/1860) by [ksylvan](https://github.com/ksylvan): fix: allow resetting required settings without validation errors
- Fix: allow resetting required settings without validation errors
- Update `Ask` to detect reset command and bypass validation
- Refactor `OnAnswer` to support new `isReset` parameter logic
- Invoke `ConfigureCustom` in `Setup` to avoid redundant re-validation
- Add unit tests ensuring required fields can be reset
## v1.4.340 (2025-12-08)
### PR [#1856](https://github.com/danielmiessler/Fabric/pull/1856) by [ksylvan](https://github.com/ksylvan): Add support for new ClaudeHaiku 4.5 models

View File

@@ -12,7 +12,7 @@ import (
func main() {
err := cli.Cli(version)
if err != nil && !flags.WroteHelp(err) {
fmt.Printf("%s\n", err)
fmt.Fprintf(os.Stderr, "%s\n", err)
os.Exit(1)
}
}

View File

@@ -1,3 +1,3 @@
package main
var version = "v1.4.340"
var version = "v1.4.343"

Binary file not shown.

View File

@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"net/http"
"os"
"strconv"
"strings"
@@ -216,7 +217,7 @@ func (an *Client) SendStream(
}
if stream.Err() != nil {
fmt.Printf("Messages stream error: %v\n", stream.Err())
fmt.Fprintf(os.Stderr, "Messages stream error: %v\n", stream.Err())
}
close(channel)
return

View File

@@ -92,7 +92,11 @@ func (o *PluginBase) Setup() (err error) {
return
}
err = o.Configure()
// After Setup, run ConfigureCustom if present, but skip re-validation
// since Ask() already validated user input (or allowed explicit reset)
if o.ConfigureCustom != nil {
err = o.ConfigureCustom()
}
return
}
@@ -198,16 +202,21 @@ func (o *SetupQuestion) Ask(label string) (err error) {
var answer string
fmt.Scanln(&answer)
answer = strings.TrimRight(answer, "\n")
isReset := strings.ToLower(answer) == AnswerReset
if answer == "" {
answer = o.Value
} else if strings.ToLower(answer) == AnswerReset {
} else if isReset {
answer = ""
}
err = o.OnAnswer(answer)
err = o.OnAnswerWithReset(answer, isReset)
return
}
func (o *SetupQuestion) OnAnswer(answer string) (err error) {
return o.OnAnswerWithReset(answer, false)
}
func (o *SetupQuestion) OnAnswerWithReset(answer string, isReset bool) (err error) {
if o.Type == SettingTypeBool {
if answer == "" {
o.Value = ""
@@ -226,6 +235,11 @@ func (o *SetupQuestion) OnAnswer(answer string) (err error) {
return
}
}
// Skip validation when explicitly resetting a value - the user intentionally
// wants to clear the value even if it's required
if isReset {
return nil
}
err = o.IsValidErr()
return
}

View File

@@ -116,6 +116,91 @@ func TestSetupQuestion_Ask(t *testing.T) {
assert.Equal(t, "user_value", setting.Value)
}
func TestSetupQuestion_Ask_Reset(t *testing.T) {
// Test that resetting a required field doesn't produce an error
setting := &Setting{
EnvVariable: "TEST_RESET_SETTING",
Value: "existing_value",
Required: true,
}
question := &SetupQuestion{
Setting: setting,
Question: "Enter test setting:",
}
input := "reset\n"
fmtInput := captureInput(input)
defer fmtInput()
err := question.Ask("TestConfigurable")
// Should NOT return an error even though the field is required
assert.NoError(t, err)
// Value should be cleared
assert.Equal(t, "", setting.Value)
}
func TestSetupQuestion_OnAnswerWithReset(t *testing.T) {
tests := []struct {
name string
setting *Setting
answer string
isReset bool
expectError bool
expectValue string
}{
{
name: "reset required field should not error",
setting: &Setting{
EnvVariable: "TEST_SETTING",
Value: "old_value",
Required: true,
},
answer: "",
isReset: true,
expectError: false,
expectValue: "",
},
{
name: "empty answer on required field should error",
setting: &Setting{
EnvVariable: "TEST_SETTING",
Value: "",
Required: true,
},
answer: "",
isReset: false,
expectError: true,
expectValue: "",
},
{
name: "valid answer on required field should not error",
setting: &Setting{
EnvVariable: "TEST_SETTING",
Value: "",
Required: true,
},
answer: "new_value",
isReset: false,
expectError: false,
expectValue: "new_value",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
question := &SetupQuestion{
Setting: tt.setting,
Question: "Test question",
}
err := question.OnAnswerWithReset(tt.answer, tt.isReset)
if tt.expectError {
assert.Error(t, err)
} else {
assert.NoError(t, err)
}
assert.Equal(t, tt.expectValue, tt.setting.Value)
})
}
}
func TestSettings_IsConfigured(t *testing.T) {
settings := Settings{
{EnvVariable: "TEST_SETTING1", Value: "value1", Required: true},

View File

@@ -1 +1 @@
"1.4.340"
"1.4.343"

16
web/pnpm-lock.yaml generated
View File

@@ -323,8 +323,8 @@ packages:
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
'@eslint-community/regexpp@4.12.1':
resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==}
'@eslint-community/regexpp@4.12.2':
resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==}
engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
'@eslint/config-array@0.19.2':
@@ -1387,8 +1387,8 @@ packages:
resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==}
hasBin: true
js-yaml@4.1.0:
resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
js-yaml@4.1.1:
resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==}
hasBin: true
jsbn@0.1.1:
@@ -2484,7 +2484,7 @@ snapshots:
eslint: 9.17.0(jiti@1.21.7)
eslint-visitor-keys: 3.4.3
'@eslint-community/regexpp@4.12.1': {}
'@eslint-community/regexpp@4.12.2': {}
'@eslint/config-array@0.19.2':
dependencies:
@@ -2510,7 +2510,7 @@ snapshots:
globals: 14.0.0
ignore: 5.3.2
import-fresh: 3.3.1
js-yaml: 4.1.0
js-yaml: 4.1.1
minimatch: 3.1.2
strip-json-comments: 3.1.1
transitivePeerDependencies:
@@ -3208,7 +3208,7 @@ snapshots:
eslint@9.17.0(jiti@1.21.7):
dependencies:
'@eslint-community/eslint-utils': 4.9.0(eslint@9.17.0(jiti@1.21.7))
'@eslint-community/regexpp': 4.12.1
'@eslint-community/regexpp': 4.12.2
'@eslint/config-array': 0.19.2
'@eslint/core': 0.9.1
'@eslint/eslintrc': 3.3.1
@@ -3604,7 +3604,7 @@ snapshots:
jiti@1.21.7: {}
js-yaml@4.1.0:
js-yaml@4.1.1:
dependencies:
argparse: 2.0.1