@gr8ful/spf 0.14.0 → 0.16.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/README.md +51 -9
- package/assets/skill/references/config.md +12 -5
- package/assets/skill/references/observability.md +57 -12
- package/assets/templates/ts-opencode.spf.config.yaml +54 -0
- package/dist/chains/index.js +1 -1
- package/dist/chains/simple_sdlc.d.ts +2 -2
- package/dist/chains/simple_sdlc.js +13 -13
- package/dist/chains/steps.d.ts +2 -2
- package/dist/chains/steps.js +35 -19
- package/dist/cli/commands/abort.d.ts +1 -1
- package/dist/cli/commands/abort.js +30 -3
- package/dist/cli/commands/doctor.js +121 -8
- package/dist/cli/commands/estimate.js +3 -3
- package/dist/cli/commands/events.js +4 -4
- package/dist/cli/commands/fanout.js +93 -21
- package/dist/cli/commands/loop.js +31 -32
- package/dist/cli/commands/migrate.js +8 -1
- package/dist/cli/commands/phases.js +2 -2
- package/dist/cli/commands/sessions.js +2 -2
- package/dist/cli/commands/trace.d.ts +28 -8
- package/dist/cli/commands/trace.js +28 -15
- package/dist/cli/commands/ui.js +15 -5
- package/dist/cli/commands/watch.js +91 -30
- package/dist/cli/index.js +3 -1
- package/dist/cli/interview.d.ts +1 -0
- package/dist/cli/interview.js +95 -5
- package/dist/core/agent_opencode.d.ts +247 -0
- package/dist/core/agent_opencode.js +590 -0
- package/dist/core/agents.d.ts +12 -12
- package/dist/core/agents.js +113 -46
- package/dist/core/console.d.ts +12 -12
- package/dist/core/console.js +25 -25
- package/dist/core/data_types.d.ts +356 -15
- package/dist/core/data_types.js +180 -7
- package/dist/core/fanout.d.ts +1 -1
- package/dist/core/fanout.js +1 -1
- package/dist/core/gates.js +14 -1
- package/dist/core/issues/github_provider.d.ts +66 -2
- package/dist/core/issues/github_provider.js +161 -2
- package/dist/core/issues/jira_provider.d.ts +50 -9
- package/dist/core/issues/jira_provider.js +62 -2
- package/dist/core/paths.d.ts +41 -4
- package/dist/core/paths.js +32 -3
- package/dist/core/quality.d.ts +7 -7
- package/dist/core/quality.js +16 -10
- package/dist/core/refine.js +2 -2
- package/dist/core/runner.d.ts +9 -3
- package/dist/core/runner.js +39 -27
- package/dist/core/session.d.ts +2 -2
- package/dist/core/session.js +39 -18
- package/dist/core/sqlite.d.ts +14 -7
- package/dist/core/sqlite.js +14 -7
- package/dist/core/trace_db.d.ts +118 -0
- package/dist/core/trace_db.js +278 -0
- package/dist/core/tracer.d.ts +64 -34
- package/dist/core/tracer.js +141 -69
- package/dist/core/watch.d.ts +4 -4
- package/dist/core/watch.js +2 -2
- package/dist/ui/server/app.js +10 -10
- package/dist/ui/server/db.d.ts +89 -21
- package/dist/ui/server/db.js +235 -99
- package/dist/ui/server/serve.d.ts +5 -1
- package/dist/ui/server/serve.js +4 -5
- package/package.json +1 -1
- package/web/assets/index-CQ3k1Y1-.css +1 -0
- package/web/assets/index-CU8tom6S.js +21 -0
- package/web/assets/overpass-latin-400-normal-BpeLJ0bs.woff2 +0 -0
- package/web/assets/overpass-latin-600-normal-25RhTNCi.woff2 +0 -0
- package/web/assets/overpass-latin-700-normal-CQX2QTgM.woff2 +0 -0
- package/web/assets/overpass-mono-latin-400-normal-VINZG6Js.woff2 +0 -0
- package/web/assets/overpass-mono-latin-700-normal-D6nRBrbd.woff2 +0 -0
- package/web/index.html +33 -2
- package/web/logo.svg +4 -4
- package/web/assets/index-C7nF068F.css +0 -1
- package/web/assets/index-mzSArcnQ.js +0 -11
- package/web/assets/play-latin-400-normal-GKW-4YV7.woff2 +0 -0
- package/web/assets/play-latin-700-normal-DyPlLDbb.woff2 +0 -0
|
@@ -671,7 +671,7 @@ export interface SandboxSpec {
|
|
|
671
671
|
}
|
|
672
672
|
export declare const AgentConfigSchema: v.ObjectSchema<{
|
|
673
673
|
readonly name: v.StringSchema<undefined>;
|
|
674
|
-
readonly coding_agent: v.OptionalSchema<v.PicklistSchema<["flue", "claude_code"], undefined>, "flue">;
|
|
674
|
+
readonly coding_agent: v.OptionalSchema<v.PicklistSchema<["flue", "claude_code", "opencode"], undefined>, "flue">;
|
|
675
675
|
readonly model: v.OptionalSchema<v.StringSchema<undefined>, "google/gemini-3.6-flash">;
|
|
676
676
|
readonly thinking: v.OptionalSchema<v.PicklistSchema<["off", "minimal", "low", "medium", "high", "xhigh", "max"], undefined>, "medium">;
|
|
677
677
|
readonly color: v.OptionalSchema<v.StringSchema<undefined>, "">;
|
|
@@ -688,7 +688,7 @@ export declare const AgentConfigSchema: v.ObjectSchema<{
|
|
|
688
688
|
}, undefined>;
|
|
689
689
|
export type AgentConfig = v.InferOutput<typeof AgentConfigSchema>;
|
|
690
690
|
export declare const ConfigDefaultsSchema: v.ObjectSchema<{
|
|
691
|
-
readonly coding_agent: v.OptionalSchema<v.PicklistSchema<["flue", "claude_code"], undefined>, "flue">;
|
|
691
|
+
readonly coding_agent: v.OptionalSchema<v.PicklistSchema<["flue", "claude_code", "opencode"], undefined>, "flue">;
|
|
692
692
|
readonly model: v.OptionalSchema<v.StringSchema<undefined>, "google/gemini-3.6-flash">;
|
|
693
693
|
readonly thinking: v.OptionalSchema<v.PicklistSchema<["off", "minimal", "low", "medium", "high", "xhigh", "max"], undefined>, "medium">;
|
|
694
694
|
readonly color: v.OptionalSchema<v.StringSchema<undefined>, "">;
|
|
@@ -763,8 +763,106 @@ export declare const OTelConfigSchema: v.ObjectSchema<{
|
|
|
763
763
|
readonly service_name: v.OptionalSchema<v.StringSchema<undefined>, "spf">;
|
|
764
764
|
}, undefined>;
|
|
765
765
|
export type OTelConfig = v.InferOutput<typeof OTelConfigSchema>;
|
|
766
|
+
/**
|
|
767
|
+
* MIGRATION NOTE (BT-issue #66, 3 PRs): `observability.db` used to be ONLY a
|
|
768
|
+
* bare string (a local sqlite path, defaulting to ".spf/data/spf.db"). This
|
|
769
|
+
* is now a discriminated shape that additionally accepts an explicit
|
|
770
|
+
* `{ kind: "sqlite", path? }` object (equivalent to the string form, just
|
|
771
|
+
* spelled out) and a `{ kind: "d1", database_id, ... }` object that names a
|
|
772
|
+
* remote Cloudflare D1 database instead of a local file. The bare-string
|
|
773
|
+
* form is unchanged and remains the default for every existing config —
|
|
774
|
+
* nothing in the wild needs to change. `resolveObservabilityDb` below
|
|
775
|
+
* normalizes all three accepted forms to one shape.
|
|
776
|
+
*
|
|
777
|
+
* PR 1 (this schema + normalizer + `paths.resolveDataPaths` plumbing) left
|
|
778
|
+
* `resolveDataPaths` refusing a `kind: "d1"` config outright — no adapter
|
|
779
|
+
* existed yet. PR 2 (`core/trace_db.ts`'s `TraceDb` interface, `LocalTraceDb`,
|
|
780
|
+
* `D1TraceDb`, and `createTraceDb()`, wired through `Tracer`/`SfDb`) removes
|
|
781
|
+
* that refusal: `resolveDataPaths` now returns a usable descriptor for
|
|
782
|
+
* either kind, and both backends are real. PR 3 wires `spf doctor`/`spf
|
|
783
|
+
* init`'s interview flow to the new option.
|
|
784
|
+
*/
|
|
785
|
+
export declare const SqliteDbConfigSchema: v.ObjectSchema<{
|
|
786
|
+
readonly kind: v.LiteralSchema<"sqlite", undefined>;
|
|
787
|
+
readonly path: v.OptionalSchema<v.StringSchema<undefined>, ".spf/data/spf.db">;
|
|
788
|
+
}, undefined>;
|
|
789
|
+
export type SqliteDbConfig = v.InferOutput<typeof SqliteDbConfigSchema>;
|
|
790
|
+
/**
|
|
791
|
+
* `account_id_env`/`api_token_env` default to the SAME env var names
|
|
792
|
+
* `core/cloudflare_provider.ts` already reads for the Cloudflare Workers AI
|
|
793
|
+
* provider (`CLOUDFLARE_ACCOUNT_ID`/`CLOUDFLARE_API_TOKEN`, see
|
|
794
|
+
* `core/providers.ts`'s `PROVIDER_ENV_KEYS.cloudflare`) — one Cloudflare
|
|
795
|
+
* account's credentials, read from the same two env vars, cover both
|
|
796
|
+
* Workers AI and a D1-backed trace db unless a config explicitly points
|
|
797
|
+
* elsewhere (e.g. a second Cloudflare account) by naming different env vars.
|
|
798
|
+
*/
|
|
799
|
+
export declare const D1DbConfigSchema: v.ObjectSchema<{
|
|
800
|
+
readonly kind: v.LiteralSchema<"d1", undefined>;
|
|
801
|
+
readonly database_id: v.StringSchema<undefined>;
|
|
802
|
+
readonly account_id_env: v.OptionalSchema<v.StringSchema<undefined>, "CLOUDFLARE_ACCOUNT_ID">;
|
|
803
|
+
readonly api_token_env: v.OptionalSchema<v.StringSchema<undefined>, "CLOUDFLARE_API_TOKEN">;
|
|
804
|
+
}, undefined>;
|
|
805
|
+
export type D1DbConfig = v.InferOutput<typeof D1DbConfigSchema>;
|
|
806
|
+
export declare const ObservabilityDbSchema: v.SchemaWithPipe<readonly [v.UnknownSchema, v.RawTransformAction<unknown, string | {
|
|
807
|
+
kind: "sqlite";
|
|
808
|
+
path: string;
|
|
809
|
+
} | {
|
|
810
|
+
kind: "d1";
|
|
811
|
+
database_id: string;
|
|
812
|
+
account_id_env: string;
|
|
813
|
+
api_token_env: string;
|
|
814
|
+
}>]>;
|
|
815
|
+
export type ObservabilityDbConfig = v.InferOutput<typeof ObservabilityDbSchema>;
|
|
816
|
+
/**
|
|
817
|
+
* What `resolveObservabilityDb` ACCEPTS — deliberately more permissive than
|
|
818
|
+
* `ObservabilityDbConfig` (that type is the schema's OUTPUT, post-default,
|
|
819
|
+
* so every optional field reads as required). This is the pre-default INPUT
|
|
820
|
+
* shape — `path`/`account_id_env`/`api_token_env` all optional, exactly
|
|
821
|
+
* what a hand-written `{kind:"sqlite"}` or `{kind:"d1", database_id:"..."}`
|
|
822
|
+
* literal looks like before `v.parse` fills its defaults in. An already-
|
|
823
|
+
* parsed `ObservabilityDbConfig` (every optional field present) satisfies
|
|
824
|
+
* this too, so the one normalizer works on config fresh off `v.parse` AND
|
|
825
|
+
* on a literal built by hand (e.g. in a test, or by a future caller that
|
|
826
|
+
* hasn't gone through the schema).
|
|
827
|
+
*/
|
|
828
|
+
export type ObservabilityDbInput = string | {
|
|
829
|
+
kind: "sqlite";
|
|
830
|
+
path?: string;
|
|
831
|
+
} | {
|
|
832
|
+
kind: "d1";
|
|
833
|
+
database_id: string;
|
|
834
|
+
account_id_env?: string;
|
|
835
|
+
api_token_env?: string;
|
|
836
|
+
};
|
|
837
|
+
/** What `resolveObservabilityDb` normalizes any of the three accepted `db:` forms to. PR 2's D1 adapter is built against this shape. */
|
|
838
|
+
export type NormalizedObservabilityDb = {
|
|
839
|
+
kind: "sqlite";
|
|
840
|
+
path: string;
|
|
841
|
+
} | {
|
|
842
|
+
kind: "d1";
|
|
843
|
+
database_id: string;
|
|
844
|
+
account_id_env: string;
|
|
845
|
+
api_token_env: string;
|
|
846
|
+
};
|
|
847
|
+
/**
|
|
848
|
+
* Normalizes `observability.db` — bare string, `{kind:"sqlite",...}`, or
|
|
849
|
+
* `{kind:"d1",...}` — to one shape. Pure and side-effect-free: does NOT
|
|
850
|
+
* resolve `path` to an absolute path (that's `paths.resolveDataPaths`'s job,
|
|
851
|
+
* which needs `repo_root` to do it) and does NOT read the D1 env vars it
|
|
852
|
+
* names (that's PR 2's adapter's job, at the point it actually needs to
|
|
853
|
+
* authenticate).
|
|
854
|
+
*/
|
|
855
|
+
export declare function resolveObservabilityDb(db: ObservabilityDbInput): NormalizedObservabilityDb;
|
|
766
856
|
export declare const ObservabilityConfigSchema: v.ObjectSchema<{
|
|
767
|
-
readonly db: v.OptionalSchema<v.
|
|
857
|
+
readonly db: v.OptionalSchema<v.SchemaWithPipe<readonly [v.UnknownSchema, v.RawTransformAction<unknown, string | {
|
|
858
|
+
kind: "sqlite";
|
|
859
|
+
path: string;
|
|
860
|
+
} | {
|
|
861
|
+
kind: "d1";
|
|
862
|
+
database_id: string;
|
|
863
|
+
account_id_env: string;
|
|
864
|
+
api_token_env: string;
|
|
865
|
+
}>]>, ".spf/data/spf.db">;
|
|
768
866
|
readonly poll_ms: v.OptionalSchema<v.NumberSchema<undefined>, 500>;
|
|
769
867
|
readonly otel: v.OptionalSchema<v.ObjectSchema<{
|
|
770
868
|
readonly endpoint: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.UrlAction<string, undefined>]>;
|
|
@@ -839,14 +937,43 @@ export declare const JiraIssueTypeMapSchema: v.ObjectSchema<{
|
|
|
839
937
|
readonly spec: v.OptionalSchema<v.StringSchema<undefined>, "Story">;
|
|
840
938
|
}, undefined>;
|
|
841
939
|
export type JiraIssueTypeMap = v.InferOutput<typeof JiraIssueTypeMapSchema>;
|
|
940
|
+
/**
|
|
941
|
+
* Optional, per-project `WatchState` -> Jira workflow-status-name map.
|
|
942
|
+
* Unlike `JiraIssueTypeMapSchema`, this has no sane universal default:
|
|
943
|
+
* "To Do" vs "Open" vs "Backlog" (and everything in between) is entirely
|
|
944
|
+
* per-project workflow configuration in Jira, so every field defaults to
|
|
945
|
+
* unset. A `WatchState` with no entry here keeps today's behavior exactly —
|
|
946
|
+
* `jira_provider.ts`'s `transition()`/`claim()` update the label only and
|
|
947
|
+
* never attempt a status change for it.
|
|
948
|
+
*
|
|
949
|
+
* Deliberately covers only the states a human's Jira board status would
|
|
950
|
+
* plausibly want to reflect (the build lane, `spec-ready` through
|
|
951
|
+
* `blocked`) — the refine-lane states (`refining`, `split-proposed`, ...)
|
|
952
|
+
* are internal bookkeeping for `core/refine.ts`, not board-visible work.
|
|
953
|
+
*
|
|
954
|
+
* `jira_provider.ts`'s `syncStatus()` is the reader; `validateStatusMap()`
|
|
955
|
+
* is what `spf watch init` and `spf watch`'s own startup check should call
|
|
956
|
+
* to confirm each configured name is a real status on the project before an
|
|
957
|
+
* unattended run relies on it — same shape as `issue_types`/
|
|
958
|
+
* `validateIssueTypes()`.
|
|
959
|
+
*/
|
|
960
|
+
export declare const JiraStatusMapSchema: v.ObjectSchema<{
|
|
961
|
+
readonly "spec-ready": v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
962
|
+
readonly ready: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
963
|
+
readonly working: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
964
|
+
readonly review: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
965
|
+
readonly done: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
966
|
+
readonly blocked: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
967
|
+
}, undefined>;
|
|
968
|
+
export type JiraStatusMap = v.InferOutput<typeof JiraStatusMapSchema>;
|
|
842
969
|
/**
|
|
843
970
|
* Only consulted when `issue_provider: jira`. Auth is `JIRA_EMAIL` +
|
|
844
971
|
* `JIRA_API_TOKEN` env vars, checked at startup like `GITHUB_TOKEN`. Whole-
|
|
845
972
|
* object replace on config-file-layer merge, like `refine`/
|
|
846
973
|
* `observability.otel` (see `agents.ts`'s `mergeRawConfig`) — an override
|
|
847
|
-
* file that touches `watch.jira` at all must repeat `issue_types
|
|
848
|
-
* wants to keep a customized mapping, same caveat
|
|
849
|
-
* `base_url`/`project_key` today.
|
|
974
|
+
* file that touches `watch.jira` at all must repeat `issue_types`/
|
|
975
|
+
* `status_map` too if it wants to keep a customized mapping, same caveat
|
|
976
|
+
* that already applies to `base_url`/`project_key` today.
|
|
850
977
|
*/
|
|
851
978
|
export declare const WatchJiraConfigSchema: v.ObjectSchema<{
|
|
852
979
|
readonly base_url: v.OptionalSchema<v.StringSchema<undefined>, "">;
|
|
@@ -873,8 +1000,85 @@ export declare const WatchJiraConfigSchema: v.ObjectSchema<{
|
|
|
873
1000
|
task: string;
|
|
874
1001
|
spec: string;
|
|
875
1002
|
}>;
|
|
1003
|
+
readonly status_map: v.OptionalSchema<v.ObjectSchema<{
|
|
1004
|
+
readonly "spec-ready": v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1005
|
+
readonly ready: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1006
|
+
readonly working: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1007
|
+
readonly review: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1008
|
+
readonly done: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1009
|
+
readonly blocked: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1010
|
+
}, undefined>, () => {
|
|
1011
|
+
"spec-ready"?: string | undefined;
|
|
1012
|
+
ready?: string | undefined;
|
|
1013
|
+
working?: string | undefined;
|
|
1014
|
+
review?: string | undefined;
|
|
1015
|
+
done?: string | undefined;
|
|
1016
|
+
blocked?: string | undefined;
|
|
1017
|
+
}>;
|
|
876
1018
|
}, undefined>;
|
|
877
1019
|
export type WatchJiraConfig = v.InferOutput<typeof WatchJiraConfigSchema>;
|
|
1020
|
+
/**
|
|
1021
|
+
* Optional, per-repo `WatchState` -> GitHub Projects v2 "Status" option-name
|
|
1022
|
+
* map — the GitHub-side twin of `JiraIssueTypeMap`'s sibling on the Jira
|
|
1023
|
+
* provider (see `jira_provider.ts`'s `status_map`). No sane universal
|
|
1024
|
+
* default: a board's Status column options ("Todo"/"In Progress"/"Done", or
|
|
1025
|
+
* anything else) are per-project configuration, so every field defaults to
|
|
1026
|
+
* unset. A `WatchState` with no entry keeps today's behavior exactly —
|
|
1027
|
+
* `github_provider.ts`'s `transition()`/`claim()` update the label only and
|
|
1028
|
+
* never touch Projects v2 for it.
|
|
1029
|
+
*
|
|
1030
|
+
* Same six build-lane states as Jira's map — the refine-lane's own
|
|
1031
|
+
* bookkeeping states (`refining`, `split-proposed`, ...) aren't board-visible
|
|
1032
|
+
* work, same reasoning as `jira_provider.ts`'s `JiraStatusMapSchema`.
|
|
1033
|
+
*
|
|
1034
|
+
* `github_provider.ts`'s `syncStatus()` is the reader; `validateStatusMap()`
|
|
1035
|
+
* is what `spf watch init` and `spf watch`'s own startup check call to
|
|
1036
|
+
* confirm each configured name is a real Status option on the configured
|
|
1037
|
+
* project before an unattended run relies on it.
|
|
1038
|
+
*/
|
|
1039
|
+
export declare const GithubStatusMapSchema: v.ObjectSchema<{
|
|
1040
|
+
readonly "spec-ready": v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1041
|
+
readonly ready: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1042
|
+
readonly working: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1043
|
+
readonly review: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1044
|
+
readonly done: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1045
|
+
readonly blocked: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1046
|
+
}, undefined>;
|
|
1047
|
+
export type GithubStatusMap = v.InferOutput<typeof GithubStatusMapSchema>;
|
|
1048
|
+
/**
|
|
1049
|
+
* Only consulted when `issue_provider: github` (or `code_host: github`) AND
|
|
1050
|
+
* `status_map` actually has an entry configured — `project_number: 0` (the
|
|
1051
|
+
* default) disables status sync outright regardless of `status_map`, since
|
|
1052
|
+
* there's no sane "guess the board" default: a repo can have zero, one, or
|
|
1053
|
+
* many Projects v2 boards, and none of them is canonical. Scoped to the
|
|
1054
|
+
* repo's OWNER (`watch.repo`'s "owner/name", the owner half) — GitHub
|
|
1055
|
+
* Projects v2 numbers are per-owner, not per-repo, so `project_number: 3`
|
|
1056
|
+
* means owner's project #3, which may or may not have this repo's issues on
|
|
1057
|
+
* it yet (`github_provider.ts`'s `syncStatus()` adds the issue to the
|
|
1058
|
+
* project itself the first time it needs to). Whole-object replace on
|
|
1059
|
+
* config-file-layer merge, like `jira`/`refine` above — an override file
|
|
1060
|
+
* that touches `watch.github` at all must repeat `status_map` too if it
|
|
1061
|
+
* wants to keep a customized mapping.
|
|
1062
|
+
*/
|
|
1063
|
+
export declare const WatchGithubConfigSchema: v.ObjectSchema<{
|
|
1064
|
+
readonly project_number: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, 0>;
|
|
1065
|
+
readonly status_map: v.OptionalSchema<v.ObjectSchema<{
|
|
1066
|
+
readonly "spec-ready": v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1067
|
+
readonly ready: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1068
|
+
readonly working: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1069
|
+
readonly review: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1070
|
+
readonly done: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1071
|
+
readonly blocked: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1072
|
+
}, undefined>, () => {
|
|
1073
|
+
"spec-ready"?: string | undefined;
|
|
1074
|
+
ready?: string | undefined;
|
|
1075
|
+
working?: string | undefined;
|
|
1076
|
+
review?: string | undefined;
|
|
1077
|
+
done?: string | undefined;
|
|
1078
|
+
blocked?: string | undefined;
|
|
1079
|
+
}>;
|
|
1080
|
+
}, undefined>;
|
|
1081
|
+
export type WatchGithubConfig = v.InferOutput<typeof WatchGithubConfigSchema>;
|
|
878
1082
|
/**
|
|
879
1083
|
* The second `spf watch` lane: decompose a `<prefix>:spec-ready` product
|
|
880
1084
|
* spec into a feature/story tree of real issues, instead of running
|
|
@@ -1024,6 +1228,21 @@ export declare const WatchConfigSchema: v.ObjectSchema<{
|
|
|
1024
1228
|
task: string;
|
|
1025
1229
|
spec: string;
|
|
1026
1230
|
}>;
|
|
1231
|
+
readonly status_map: v.OptionalSchema<v.ObjectSchema<{
|
|
1232
|
+
readonly "spec-ready": v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1233
|
+
readonly ready: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1234
|
+
readonly working: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1235
|
+
readonly review: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1236
|
+
readonly done: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1237
|
+
readonly blocked: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1238
|
+
}, undefined>, () => {
|
|
1239
|
+
"spec-ready"?: string | undefined;
|
|
1240
|
+
ready?: string | undefined;
|
|
1241
|
+
working?: string | undefined;
|
|
1242
|
+
review?: string | undefined;
|
|
1243
|
+
done?: string | undefined;
|
|
1244
|
+
blocked?: string | undefined;
|
|
1245
|
+
}>;
|
|
1027
1246
|
}, undefined>, () => {
|
|
1028
1247
|
base_url: string;
|
|
1029
1248
|
project_key: string;
|
|
@@ -1035,6 +1254,42 @@ export declare const WatchConfigSchema: v.ObjectSchema<{
|
|
|
1035
1254
|
task: string;
|
|
1036
1255
|
spec: string;
|
|
1037
1256
|
};
|
|
1257
|
+
status_map: {
|
|
1258
|
+
"spec-ready"?: string | undefined;
|
|
1259
|
+
ready?: string | undefined;
|
|
1260
|
+
working?: string | undefined;
|
|
1261
|
+
review?: string | undefined;
|
|
1262
|
+
done?: string | undefined;
|
|
1263
|
+
blocked?: string | undefined;
|
|
1264
|
+
};
|
|
1265
|
+
}>;
|
|
1266
|
+
readonly github: v.OptionalSchema<v.ObjectSchema<{
|
|
1267
|
+
readonly project_number: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, 0>;
|
|
1268
|
+
readonly status_map: v.OptionalSchema<v.ObjectSchema<{
|
|
1269
|
+
readonly "spec-ready": v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1270
|
+
readonly ready: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1271
|
+
readonly working: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1272
|
+
readonly review: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1273
|
+
readonly done: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1274
|
+
readonly blocked: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1275
|
+
}, undefined>, () => {
|
|
1276
|
+
"spec-ready"?: string | undefined;
|
|
1277
|
+
ready?: string | undefined;
|
|
1278
|
+
working?: string | undefined;
|
|
1279
|
+
review?: string | undefined;
|
|
1280
|
+
done?: string | undefined;
|
|
1281
|
+
blocked?: string | undefined;
|
|
1282
|
+
}>;
|
|
1283
|
+
}, undefined>, () => {
|
|
1284
|
+
project_number: number;
|
|
1285
|
+
status_map: {
|
|
1286
|
+
"spec-ready"?: string | undefined;
|
|
1287
|
+
ready?: string | undefined;
|
|
1288
|
+
working?: string | undefined;
|
|
1289
|
+
review?: string | undefined;
|
|
1290
|
+
done?: string | undefined;
|
|
1291
|
+
blocked?: string | undefined;
|
|
1292
|
+
};
|
|
1038
1293
|
}>;
|
|
1039
1294
|
readonly refine: v.OptionalSchema<v.ObjectSchema<{
|
|
1040
1295
|
readonly enabled: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
|
|
@@ -1147,7 +1402,7 @@ export type ReviewConfig = v.InferOutput<typeof ReviewConfigSchema>;
|
|
|
1147
1402
|
*/
|
|
1148
1403
|
export declare const TierSchema: v.ObjectSchema<{
|
|
1149
1404
|
readonly name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
1150
|
-
readonly coding_agent: v.OptionalSchema<v.PicklistSchema<["flue", "claude_code"], undefined>, "flue">;
|
|
1405
|
+
readonly coding_agent: v.OptionalSchema<v.PicklistSchema<["flue", "claude_code", "opencode"], undefined>, "flue">;
|
|
1151
1406
|
readonly model: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
1152
1407
|
}, undefined>;
|
|
1153
1408
|
export type Tier = v.InferOutput<typeof TierSchema>;
|
|
@@ -1182,7 +1437,7 @@ export declare const TieringConfigSchema: v.ObjectSchema<{
|
|
|
1182
1437
|
readonly enabled: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
|
|
1183
1438
|
readonly tiers: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
|
|
1184
1439
|
readonly name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
1185
|
-
readonly coding_agent: v.OptionalSchema<v.PicklistSchema<["flue", "claude_code"], undefined>, "flue">;
|
|
1440
|
+
readonly coding_agent: v.OptionalSchema<v.PicklistSchema<["flue", "claude_code", "opencode"], undefined>, "flue">;
|
|
1186
1441
|
readonly model: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
1187
1442
|
}, undefined>, undefined>, () => never[]>;
|
|
1188
1443
|
readonly roles: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.StringSchema<undefined>, undefined>, () => {}>;
|
|
@@ -1191,7 +1446,7 @@ export type TieringConfig = v.InferOutput<typeof TieringConfigSchema>;
|
|
|
1191
1446
|
export declare const SFConfigSchema: v.ObjectSchema<{
|
|
1192
1447
|
readonly env: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.StringSchema<undefined>, undefined>, () => {}>;
|
|
1193
1448
|
readonly defaults: v.OptionalSchema<v.ObjectSchema<{
|
|
1194
|
-
readonly coding_agent: v.OptionalSchema<v.PicklistSchema<["flue", "claude_code"], undefined>, "flue">;
|
|
1449
|
+
readonly coding_agent: v.OptionalSchema<v.PicklistSchema<["flue", "claude_code", "opencode"], undefined>, "flue">;
|
|
1195
1450
|
readonly model: v.OptionalSchema<v.StringSchema<undefined>, "google/gemini-3.6-flash">;
|
|
1196
1451
|
readonly thinking: v.OptionalSchema<v.PicklistSchema<["off", "minimal", "low", "medium", "high", "xhigh", "max"], undefined>, "medium">;
|
|
1197
1452
|
readonly color: v.OptionalSchema<v.StringSchema<undefined>, "">;
|
|
@@ -1244,7 +1499,7 @@ export declare const SFConfigSchema: v.ObjectSchema<{
|
|
|
1244
1499
|
readonly max_run_cost: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.GtValueAction<number, 0, undefined>]>, undefined>;
|
|
1245
1500
|
readonly max_run_tokens: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.GtValueAction<number, 0, undefined>]>, undefined>;
|
|
1246
1501
|
}, undefined>, () => {
|
|
1247
|
-
coding_agent: "claude_code" | "flue";
|
|
1502
|
+
coding_agent: "claude_code" | "flue" | "opencode";
|
|
1248
1503
|
model: string;
|
|
1249
1504
|
thinking: "high" | "low" | "max" | "medium" | "minimal" | "off" | "xhigh";
|
|
1250
1505
|
color: string;
|
|
@@ -1256,7 +1511,15 @@ export declare const SFConfigSchema: v.ObjectSchema<{
|
|
|
1256
1511
|
max_run_tokens?: number | undefined;
|
|
1257
1512
|
}>;
|
|
1258
1513
|
readonly observability: v.OptionalSchema<v.ObjectSchema<{
|
|
1259
|
-
readonly db: v.OptionalSchema<v.
|
|
1514
|
+
readonly db: v.OptionalSchema<v.SchemaWithPipe<readonly [v.UnknownSchema, v.RawTransformAction<unknown, string | {
|
|
1515
|
+
kind: "sqlite";
|
|
1516
|
+
path: string;
|
|
1517
|
+
} | {
|
|
1518
|
+
kind: "d1";
|
|
1519
|
+
database_id: string;
|
|
1520
|
+
account_id_env: string;
|
|
1521
|
+
api_token_env: string;
|
|
1522
|
+
}>]>, ".spf/data/spf.db">;
|
|
1260
1523
|
readonly poll_ms: v.OptionalSchema<v.NumberSchema<undefined>, 500>;
|
|
1261
1524
|
readonly otel: v.OptionalSchema<v.ObjectSchema<{
|
|
1262
1525
|
readonly endpoint: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.UrlAction<string, undefined>]>;
|
|
@@ -1264,7 +1527,15 @@ export declare const SFConfigSchema: v.ObjectSchema<{
|
|
|
1264
1527
|
readonly service_name: v.OptionalSchema<v.StringSchema<undefined>, "spf">;
|
|
1265
1528
|
}, undefined>, undefined>;
|
|
1266
1529
|
}, undefined>, () => {
|
|
1267
|
-
db: string
|
|
1530
|
+
db: string | {
|
|
1531
|
+
kind: "sqlite";
|
|
1532
|
+
path: string;
|
|
1533
|
+
} | {
|
|
1534
|
+
kind: "d1";
|
|
1535
|
+
database_id: string;
|
|
1536
|
+
account_id_env: string;
|
|
1537
|
+
api_token_env: string;
|
|
1538
|
+
};
|
|
1268
1539
|
poll_ms: number;
|
|
1269
1540
|
otel?: {
|
|
1270
1541
|
endpoint: string;
|
|
@@ -1276,7 +1547,7 @@ export declare const SFConfigSchema: v.ObjectSchema<{
|
|
|
1276
1547
|
}>;
|
|
1277
1548
|
readonly agents: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
|
|
1278
1549
|
readonly name: v.StringSchema<undefined>;
|
|
1279
|
-
readonly coding_agent: v.OptionalSchema<v.PicklistSchema<["flue", "claude_code"], undefined>, "flue">;
|
|
1550
|
+
readonly coding_agent: v.OptionalSchema<v.PicklistSchema<["flue", "claude_code", "opencode"], undefined>, "flue">;
|
|
1280
1551
|
readonly model: v.OptionalSchema<v.StringSchema<undefined>, "google/gemini-3.6-flash">;
|
|
1281
1552
|
readonly thinking: v.OptionalSchema<v.PicklistSchema<["off", "minimal", "low", "medium", "high", "xhigh", "max"], undefined>, "medium">;
|
|
1282
1553
|
readonly color: v.OptionalSchema<v.StringSchema<undefined>, "">;
|
|
@@ -1363,6 +1634,21 @@ export declare const SFConfigSchema: v.ObjectSchema<{
|
|
|
1363
1634
|
task: string;
|
|
1364
1635
|
spec: string;
|
|
1365
1636
|
}>;
|
|
1637
|
+
readonly status_map: v.OptionalSchema<v.ObjectSchema<{
|
|
1638
|
+
readonly "spec-ready": v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1639
|
+
readonly ready: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1640
|
+
readonly working: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1641
|
+
readonly review: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1642
|
+
readonly done: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1643
|
+
readonly blocked: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1644
|
+
}, undefined>, () => {
|
|
1645
|
+
"spec-ready"?: string | undefined;
|
|
1646
|
+
ready?: string | undefined;
|
|
1647
|
+
working?: string | undefined;
|
|
1648
|
+
review?: string | undefined;
|
|
1649
|
+
done?: string | undefined;
|
|
1650
|
+
blocked?: string | undefined;
|
|
1651
|
+
}>;
|
|
1366
1652
|
}, undefined>, () => {
|
|
1367
1653
|
base_url: string;
|
|
1368
1654
|
project_key: string;
|
|
@@ -1374,6 +1660,42 @@ export declare const SFConfigSchema: v.ObjectSchema<{
|
|
|
1374
1660
|
task: string;
|
|
1375
1661
|
spec: string;
|
|
1376
1662
|
};
|
|
1663
|
+
status_map: {
|
|
1664
|
+
"spec-ready"?: string | undefined;
|
|
1665
|
+
ready?: string | undefined;
|
|
1666
|
+
working?: string | undefined;
|
|
1667
|
+
review?: string | undefined;
|
|
1668
|
+
done?: string | undefined;
|
|
1669
|
+
blocked?: string | undefined;
|
|
1670
|
+
};
|
|
1671
|
+
}>;
|
|
1672
|
+
readonly github: v.OptionalSchema<v.ObjectSchema<{
|
|
1673
|
+
readonly project_number: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, 0>;
|
|
1674
|
+
readonly status_map: v.OptionalSchema<v.ObjectSchema<{
|
|
1675
|
+
readonly "spec-ready": v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1676
|
+
readonly ready: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1677
|
+
readonly working: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1678
|
+
readonly review: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1679
|
+
readonly done: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1680
|
+
readonly blocked: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1681
|
+
}, undefined>, () => {
|
|
1682
|
+
"spec-ready"?: string | undefined;
|
|
1683
|
+
ready?: string | undefined;
|
|
1684
|
+
working?: string | undefined;
|
|
1685
|
+
review?: string | undefined;
|
|
1686
|
+
done?: string | undefined;
|
|
1687
|
+
blocked?: string | undefined;
|
|
1688
|
+
}>;
|
|
1689
|
+
}, undefined>, () => {
|
|
1690
|
+
project_number: number;
|
|
1691
|
+
status_map: {
|
|
1692
|
+
"spec-ready"?: string | undefined;
|
|
1693
|
+
ready?: string | undefined;
|
|
1694
|
+
working?: string | undefined;
|
|
1695
|
+
review?: string | undefined;
|
|
1696
|
+
done?: string | undefined;
|
|
1697
|
+
blocked?: string | undefined;
|
|
1698
|
+
};
|
|
1377
1699
|
}>;
|
|
1378
1700
|
readonly refine: v.OptionalSchema<v.ObjectSchema<{
|
|
1379
1701
|
readonly enabled: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
|
|
@@ -1421,6 +1743,25 @@ export declare const SFConfigSchema: v.ObjectSchema<{
|
|
|
1421
1743
|
task: string;
|
|
1422
1744
|
spec: string;
|
|
1423
1745
|
};
|
|
1746
|
+
status_map: {
|
|
1747
|
+
"spec-ready"?: string | undefined;
|
|
1748
|
+
ready?: string | undefined;
|
|
1749
|
+
working?: string | undefined;
|
|
1750
|
+
review?: string | undefined;
|
|
1751
|
+
done?: string | undefined;
|
|
1752
|
+
blocked?: string | undefined;
|
|
1753
|
+
};
|
|
1754
|
+
};
|
|
1755
|
+
github: {
|
|
1756
|
+
project_number: number;
|
|
1757
|
+
status_map: {
|
|
1758
|
+
"spec-ready"?: string | undefined;
|
|
1759
|
+
ready?: string | undefined;
|
|
1760
|
+
working?: string | undefined;
|
|
1761
|
+
review?: string | undefined;
|
|
1762
|
+
done?: string | undefined;
|
|
1763
|
+
blocked?: string | undefined;
|
|
1764
|
+
};
|
|
1424
1765
|
};
|
|
1425
1766
|
refine: {
|
|
1426
1767
|
enabled: boolean;
|
|
@@ -1467,7 +1808,7 @@ export declare const SFConfigSchema: v.ObjectSchema<{
|
|
|
1467
1808
|
readonly enabled: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
|
|
1468
1809
|
readonly tiers: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
|
|
1469
1810
|
readonly name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
1470
|
-
readonly coding_agent: v.OptionalSchema<v.PicklistSchema<["flue", "claude_code"], undefined>, "flue">;
|
|
1811
|
+
readonly coding_agent: v.OptionalSchema<v.PicklistSchema<["flue", "claude_code", "opencode"], undefined>, "flue">;
|
|
1471
1812
|
readonly model: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
1472
1813
|
}, undefined>, undefined>, () => never[]>;
|
|
1473
1814
|
readonly roles: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.StringSchema<undefined>, undefined>, () => {}>;
|
|
@@ -1475,7 +1816,7 @@ export declare const SFConfigSchema: v.ObjectSchema<{
|
|
|
1475
1816
|
enabled: boolean;
|
|
1476
1817
|
tiers: {
|
|
1477
1818
|
name: string;
|
|
1478
|
-
coding_agent: "claude_code" | "flue";
|
|
1819
|
+
coding_agent: "claude_code" | "flue" | "opencode";
|
|
1479
1820
|
model: string;
|
|
1480
1821
|
}[];
|
|
1481
1822
|
roles: {
|