@clipboard-health/groundcrew 4.46.2 → 4.46.4
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/clearance-allow-hosts +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/lib/adapterDefinition.d.ts +30 -0
- package/dist/lib/adapterDefinition.d.ts.map +1 -1
- package/dist/lib/adapters/catalog.d.ts +36 -0
- package/dist/lib/adapters/catalog.d.ts.map +1 -0
- package/dist/lib/adapters/catalog.js +42 -0
- package/dist/lib/adapters/linear/client.d.ts.map +1 -1
- package/dist/lib/adapters/linear/client.js +6 -2
- package/dist/lib/adapters/linear/index.d.ts.map +1 -1
- package/dist/lib/adapters/linear/index.js +5 -0
- package/dist/lib/adapters/registry.d.ts +11 -1
- package/dist/lib/adapters/registry.d.ts.map +1 -1
- package/dist/lib/adapters/registry.js +22 -2
- package/dist/lib/adapters/shell/discovery.d.ts +39 -0
- package/dist/lib/adapters/shell/discovery.d.ts.map +1 -0
- package/dist/lib/adapters/shell/discovery.js +94 -0
- package/dist/lib/adapters/shell/index.d.ts.map +1 -1
- package/dist/lib/adapters/shell/index.js +6 -0
- package/dist/lib/adapters/shell/install.d.ts +18 -0
- package/dist/lib/adapters/shell/install.d.ts.map +1 -0
- package/dist/lib/adapters/shell/install.js +36 -0
- package/dist/lib/adapters/shell/manifest.d.ts +69 -0
- package/dist/lib/adapters/shell/manifest.d.ts.map +1 -0
- package/dist/lib/adapters/shell/manifest.js +63 -0
- package/dist/lib/adapters/shell/manifestAdapter.d.ts +26 -0
- package/dist/lib/adapters/shell/manifestAdapter.d.ts.map +1 -0
- package/dist/lib/adapters/shell/manifestAdapter.js +64 -0
- package/dist/lib/adapters/todo-txt/index.d.ts.map +1 -1
- package/dist/lib/adapters/todo-txt/index.js +4 -0
- package/dist/lib/config.d.ts +14 -1
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/sourceCapabilities.d.ts.map +1 -1
- package/dist/lib/sourceCapabilities.js +31 -1
- package/package.json +11 -11
package/clearance-allow-hosts
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -14,7 +14,10 @@ export { resolveAgentFor, resolveRepositoryFor, type AgentResolution, type Repos
|
|
|
14
14
|
export { getUsageByAgent, type UsageByAgent } from "./lib/usage.ts";
|
|
15
15
|
export { type Board, createBoard } from "./lib/board.ts";
|
|
16
16
|
export { buildSources, buildSourcesWith } from "./lib/buildSources.ts";
|
|
17
|
-
export type { AdapterContext, AdapterDefinition } from "./lib/adapterDefinition.ts";
|
|
17
|
+
export type { AdapterContext, AdapterDefinition, AdapterMeta, AdapterOrigin, } from "./lib/adapterDefinition.ts";
|
|
18
18
|
export { adapterRegistry, type AdapterLoader, buildRegistry, buildSourceConfigSchema, listAdapterDirectories, } from "./lib/adapters/registry.ts";
|
|
19
|
+
export { listTaskSources, type TaskSourceCatalogEntry } from "./lib/adapters/catalog.ts";
|
|
20
|
+
export { getTaskSourceManifest } from "./lib/adapters/shell/discovery.ts";
|
|
21
|
+
export type { SourceManifest } from "./lib/adapters/shell/manifest.ts";
|
|
19
22
|
export { AmbiguousTaskError, type Blocker as CanonicalBlocker, type BoardState as CanonicalBoardState, type CanonicalStatus, type GroundcrewIssue as CanonicalGroundcrewIssue, type Issue as CanonicalIssue, isGroundcrewIssue as isCanonicalGroundcrewIssue, type ParentSkip as CanonicalParentSkip, type TaskSource, } from "./lib/taskSource.ts";
|
|
20
23
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAChG,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EACL,kBAAkB,EAClB,KAAK,yBAAyB,GAC/B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,KAAK,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAC7F,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAC1F,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAClE,YAAY,EACV,MAAM,EACN,YAAY,EACZ,eAAe,EACf,eAAe,EACf,cAAc,EACd,YAAY,GACb,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EACL,YAAY,EACZ,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACd,KAAK,iBAAiB,EACtB,KAAK,QAAQ,GACd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,oBAAoB,EACpB,yBAAyB,EACzB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,WAAW,EACX,mBAAmB,EACnB,0BAA0B,EAC1B,wBAAwB,EACxB,KAAK,cAAc,GACpB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,KAAK,eAAe,EACpB,KAAK,oBAAoB,GAC1B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,EAAE,KAAK,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACvE,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAChG,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EACL,kBAAkB,EAClB,KAAK,yBAAyB,GAC/B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,KAAK,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAC7F,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAC1F,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAClE,YAAY,EACV,MAAM,EACN,YAAY,EACZ,eAAe,EACf,eAAe,EACf,cAAc,EACd,YAAY,GACb,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EACL,YAAY,EACZ,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACd,KAAK,iBAAiB,EACtB,KAAK,QAAQ,GACd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,oBAAoB,EACpB,yBAAyB,EACzB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,WAAW,EACX,mBAAmB,EACnB,0BAA0B,EAC1B,wBAAwB,EACxB,KAAK,cAAc,GACpB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,KAAK,eAAe,EACpB,KAAK,oBAAoB,GAC1B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,EAAE,KAAK,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACvE,YAAY,EACV,cAAc,EACd,iBAAiB,EACjB,WAAW,EACX,aAAa,GACd,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,eAAe,EACf,KAAK,aAAa,EAClB,aAAa,EACb,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACzF,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,YAAY,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AACvE,OAAO,EACL,kBAAkB,EAClB,KAAK,OAAO,IAAI,gBAAgB,EAChC,KAAK,UAAU,IAAI,mBAAmB,EACtC,KAAK,eAAe,EACpB,KAAK,eAAe,IAAI,wBAAwB,EAChD,KAAK,KAAK,IAAI,cAAc,EAC5B,iBAAiB,IAAI,0BAA0B,EAC/C,KAAK,UAAU,IAAI,mBAAmB,EACtC,KAAK,UAAU,GAChB,MAAM,qBAAqB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -14,4 +14,6 @@ export { getUsageByAgent } from "./lib/usage.js";
|
|
|
14
14
|
export { createBoard } from "./lib/board.js";
|
|
15
15
|
export { buildSources, buildSourcesWith } from "./lib/buildSources.js";
|
|
16
16
|
export { adapterRegistry, buildRegistry, buildSourceConfigSchema, listAdapterDirectories, } from "./lib/adapters/registry.js";
|
|
17
|
+
export { listTaskSources } from "./lib/adapters/catalog.js";
|
|
18
|
+
export { getTaskSourceManifest } from "./lib/adapters/shell/discovery.js";
|
|
17
19
|
export { AmbiguousTaskError, isGroundcrewIssue as isCanonicalGroundcrewIssue, } from "./lib/taskSource.js";
|
|
@@ -16,6 +16,30 @@ import type { TaskSource } from "./taskSource.ts";
|
|
|
16
16
|
export interface AdapterContext {
|
|
17
17
|
readonly globalConfig: ResolvedConfig;
|
|
18
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* Where an adapter came from. A superset of a manifest's `ManifestOrigin`
|
|
21
|
+
* (`package | user`, see `./adapters/shell/discovery.ts`): code adapters shipped
|
|
22
|
+
* in this package are `builtin`, discovered manifests are `package` (bundled) or
|
|
23
|
+
* `user` (installed under `~/.config/groundcrew/task-sources`).
|
|
24
|
+
*/
|
|
25
|
+
export type AdapterOrigin = "builtin" | "package" | "user";
|
|
26
|
+
/**
|
|
27
|
+
* Descriptive metadata that lets the unified catalog (`./adapters/catalog.ts`)
|
|
28
|
+
* list every enable-by-kind source uniformly, whatever its runtime. Purely the
|
|
29
|
+
* descriptor layer; execution stays per-adapter. The generic `shell` adapter
|
|
30
|
+
* sets `template: true` so it is excluded from the catalog (it is a
|
|
31
|
+
* bring-your-own-scripts escape hatch, not an installable source).
|
|
32
|
+
*/
|
|
33
|
+
export interface AdapterMeta {
|
|
34
|
+
/** One-line human summary shown when enumerating installable sources. */
|
|
35
|
+
readonly description: string;
|
|
36
|
+
/** True when enabling the source needs a secret/token (e.g. an API key). */
|
|
37
|
+
readonly requiresCredentials?: boolean;
|
|
38
|
+
/** True for the generic `shell` escape hatch; excluded from the catalog. */
|
|
39
|
+
readonly template?: boolean;
|
|
40
|
+
/** Provenance of the adapter. */
|
|
41
|
+
readonly origin: AdapterOrigin;
|
|
42
|
+
}
|
|
19
43
|
export interface AdapterDefinition<TSchema extends z.ZodType = z.ZodType> {
|
|
20
44
|
/** Discriminator value used in `SourceConfig.kind`. Must equal the directory name. */
|
|
21
45
|
readonly kind: string;
|
|
@@ -23,5 +47,11 @@ export interface AdapterDefinition<TSchema extends z.ZodType = z.ZodType> {
|
|
|
23
47
|
readonly configSchema: TSchema;
|
|
24
48
|
/** Builds a TaskSource from a validated config and the shared adapter context. */
|
|
25
49
|
readonly create: (config: z.infer<TSchema>, context: AdapterContext) => TaskSource;
|
|
50
|
+
/**
|
|
51
|
+
* Optional descriptive metadata for the unified source catalog. Every
|
|
52
|
+
* built-in and manifest adapter sets it; an adapter without `meta` is simply
|
|
53
|
+
* absent from `listTaskSources()`.
|
|
54
|
+
*/
|
|
55
|
+
readonly meta?: AdapterMeta;
|
|
26
56
|
}
|
|
27
57
|
//# sourceMappingURL=adapterDefinition.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapterDefinition.d.ts","sourceRoot":"","sources":["../../src/lib/adapterDefinition.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,YAAY,EAAE,cAAc,CAAC;CACvC;AAED,MAAM,WAAW,iBAAiB,CAAC,OAAO,SAAS,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO;IACtE,sFAAsF;IACtF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,8FAA8F;IAC9F,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,kFAAkF;IAClF,QAAQ,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,cAAc,KAAK,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"adapterDefinition.d.ts","sourceRoot":"","sources":["../../src/lib/adapterDefinition.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,YAAY,EAAE,cAAc,CAAC;CACvC;AAED;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;AAE3D;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,yEAAyE;IACzE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,4EAA4E;IAC5E,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IACvC,4EAA4E;IAC5E,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,iCAAiC;IACjC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;CAChC;AAED,MAAM,WAAW,iBAAiB,CAAC,OAAO,SAAS,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO;IACtE,sFAAsF;IACtF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,8FAA8F;IAC9F,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,kFAAkF;IAClF,QAAQ,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,cAAc,KAAK,UAAU,CAAC;IACnF;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC;CAC7B"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified task-source catalog: one descriptor list over every enable-by-kind
|
|
3
|
+
* source, built-in code adapters (`linear`, `todo-txt`) and discovered manifest
|
|
4
|
+
* sources (`jira`, ...) alike. Only the descriptive layer is unified; execution
|
|
5
|
+
* stays per-adapter (a code adapter is not reimplemented as a shell manifest).
|
|
6
|
+
*
|
|
7
|
+
* Lives above `registry.ts` and `discovery.ts` and imports the registry
|
|
8
|
+
* one-directionally, so putting `listTaskSources` here (rather than in
|
|
9
|
+
* `discovery.ts`, which `registry.ts` already imports) keeps the module graph a
|
|
10
|
+
* DAG. crew-config calls this to enumerate installable sources instead of
|
|
11
|
+
* hardcoding presets.
|
|
12
|
+
*/
|
|
13
|
+
import type { AdapterDefinition, AdapterOrigin } from "../adapterDefinition.ts";
|
|
14
|
+
/**
|
|
15
|
+
* One row of the source catalog. `requiresCredentials` is always concrete (an
|
|
16
|
+
* adapter's optional `meta.requiresCredentials` defaults to `false`) so callers
|
|
17
|
+
* never branch on `undefined`.
|
|
18
|
+
*/
|
|
19
|
+
export interface TaskSourceCatalogEntry {
|
|
20
|
+
readonly name: string;
|
|
21
|
+
readonly description: string;
|
|
22
|
+
readonly origin: AdapterOrigin;
|
|
23
|
+
readonly requiresCredentials: boolean;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Pure projection of a merged registry into catalog rows. Adapters without
|
|
27
|
+
* `meta`, and the generic `shell` template (`meta.template`), are excluded; the
|
|
28
|
+
* template is a bring-your-own-scripts escape hatch, not an installable source.
|
|
29
|
+
*/
|
|
30
|
+
export declare function catalogFromRegistry(registry: Record<string, AdapterDefinition>): TaskSourceCatalogEntry[];
|
|
31
|
+
/**
|
|
32
|
+
* The production catalog: awaits the merged adapter registry (code adapters plus
|
|
33
|
+
* discovered manifest sources) and projects it into catalog rows.
|
|
34
|
+
*/
|
|
35
|
+
export declare function listTaskSources(): Promise<TaskSourceCatalogEntry[]>;
|
|
36
|
+
//# sourceMappingURL=catalog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../../src/lib/adapters/catalog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAIhF;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAC;CACvC;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,GAC1C,sBAAsB,EAAE,CAe1B;AAED;;;GAGG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAGzE"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified task-source catalog: one descriptor list over every enable-by-kind
|
|
3
|
+
* source, built-in code adapters (`linear`, `todo-txt`) and discovered manifest
|
|
4
|
+
* sources (`jira`, ...) alike. Only the descriptive layer is unified; execution
|
|
5
|
+
* stays per-adapter (a code adapter is not reimplemented as a shell manifest).
|
|
6
|
+
*
|
|
7
|
+
* Lives above `registry.ts` and `discovery.ts` and imports the registry
|
|
8
|
+
* one-directionally, so putting `listTaskSources` here (rather than in
|
|
9
|
+
* `discovery.ts`, which `registry.ts` already imports) keeps the module graph a
|
|
10
|
+
* DAG. crew-config calls this to enumerate installable sources instead of
|
|
11
|
+
* hardcoding presets.
|
|
12
|
+
*/
|
|
13
|
+
import { adapterRegistry } from "./registry.js";
|
|
14
|
+
/**
|
|
15
|
+
* Pure projection of a merged registry into catalog rows. Adapters without
|
|
16
|
+
* `meta`, and the generic `shell` template (`meta.template`), are excluded; the
|
|
17
|
+
* template is a bring-your-own-scripts escape hatch, not an installable source.
|
|
18
|
+
*/
|
|
19
|
+
export function catalogFromRegistry(registry) {
|
|
20
|
+
const entries = [];
|
|
21
|
+
for (const adapter of Object.values(registry)) {
|
|
22
|
+
const { meta } = adapter;
|
|
23
|
+
if (meta === undefined || meta.template === true) {
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
entries.push({
|
|
27
|
+
name: adapter.kind,
|
|
28
|
+
description: meta.description,
|
|
29
|
+
origin: meta.origin,
|
|
30
|
+
requiresCredentials: meta.requiresCredentials ?? false,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
return entries;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The production catalog: awaits the merged adapter registry (code adapters plus
|
|
37
|
+
* discovered manifest sources) and projects it into catalog rows.
|
|
38
|
+
*/
|
|
39
|
+
export async function listTaskSources() {
|
|
40
|
+
const registry = await adapterRegistry;
|
|
41
|
+
return catalogFromRegistry(registry);
|
|
42
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/linear/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI3C,QAAA,MAAM,sBAAsB,YAAI,2BAA2B,EAAE,gBAAgB,CAAU,CAAC;AAExF,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzE,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,kBAAkB,CAAC;CAC5B;AAED,wBAAgB,mBAAmB,IAAI,oBAAoB,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/linear/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI3C,QAAA,MAAM,sBAAsB,YAAI,2BAA2B,EAAE,gBAAgB,CAAU,CAAC;AAExF,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzE,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,kBAAkB,CAAC;CAC5B;AAED,wBAAgB,mBAAmB,IAAI,oBAAoB,GAAG,SAAS,CAYtE;AAED,wBAAgB,eAAe,IAAI,YAAY,CAQ9C;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,YAAY,GAAG,MAAM,YAAY,CAMhF"}
|
|
@@ -4,9 +4,13 @@ const LINEAR_API_KEY_SOURCES = ["GROUNDCREW_LINEAR_API_KEY", "LINEAR_API_KEY"];
|
|
|
4
4
|
export function resolveLinearApiKey() {
|
|
5
5
|
for (const source of LINEAR_API_KEY_SOURCES) {
|
|
6
6
|
const value = readEnvironmentVariable(source);
|
|
7
|
-
if (value
|
|
8
|
-
|
|
7
|
+
if (value === undefined) {
|
|
8
|
+
continue;
|
|
9
9
|
}
|
|
10
|
+
if (value.length === 0) {
|
|
11
|
+
continue;
|
|
12
|
+
}
|
|
13
|
+
return { value, source };
|
|
10
14
|
}
|
|
11
15
|
return undefined;
|
|
12
16
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/linear/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAGpE,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAExD,QAAA,MAAM,UAAU,EAAE,iBAAiB,CAAC,OAAO,yBAAyB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/linear/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAGpE,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAExD,QAAA,MAAM,UAAU,EAAE,iBAAiB,CAAC,OAAO,yBAAyB,CAUnE,CAAC;eAEa,UAAU;AAEzB,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -4,5 +4,10 @@ const definition = {
|
|
|
4
4
|
kind: "linear",
|
|
5
5
|
configSchema: linearAdapterConfigSchema,
|
|
6
6
|
create: createLinearTaskSource,
|
|
7
|
+
meta: {
|
|
8
|
+
description: "Pick up Linear issues assigned to your API key's viewer that carry an agent-* label.",
|
|
9
|
+
requiresCredentials: true,
|
|
10
|
+
origin: "builtin",
|
|
11
|
+
},
|
|
7
12
|
};
|
|
8
13
|
export default definition;
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import { z } from "zod";
|
|
13
13
|
import type { AdapterDefinition } from "../adapterDefinition.ts";
|
|
14
|
+
import { type DiscoveredManifest } from "./shell/discovery.ts";
|
|
14
15
|
export type AdapterLoader = (directoryName: string) => Promise<AdapterDefinition>;
|
|
15
16
|
/**
|
|
16
17
|
* Pure logic: given a list of subdirectory names and an async loader, build a
|
|
@@ -30,9 +31,18 @@ export declare function buildRegistry(directoryNames: readonly string[], loader:
|
|
|
30
31
|
* semantically equivalent here because each kind has a unique literal.
|
|
31
32
|
*/
|
|
32
33
|
export declare function buildSourceConfigSchema(registry: Record<string, AdapterDefinition>): z.ZodType;
|
|
34
|
+
/**
|
|
35
|
+
* Fold discovered manifest sources into a code-adapter registry. Each becomes
|
|
36
|
+
* an adapter keyed by its manifest name. A manifest may not shadow a built-in
|
|
37
|
+
* code-adapter kind (`linear`, `shell`, `todo-txt`) - those are reserved, so a
|
|
38
|
+
* collision is a hard error. Manifest-vs-manifest precedence (user over
|
|
39
|
+
* package) is already resolved by discovery, so `discovered` has no duplicates.
|
|
40
|
+
*/
|
|
41
|
+
export declare function mergeManifestAdapters(codeRegistry: Record<string, AdapterDefinition>, discovered: readonly DiscoveredManifest[]): Record<string, AdapterDefinition>;
|
|
33
42
|
export declare function listAdapterDirectories(baseDir: string): string[];
|
|
34
43
|
/**
|
|
35
|
-
* Production registry.
|
|
44
|
+
* Production registry. Scans `src/lib/adapters/` for code adapters, then folds
|
|
45
|
+
* in the manifest sources discovered under the package + user task-sources roots.
|
|
36
46
|
*/
|
|
37
47
|
export declare const adapterRegistry: Promise<Record<string, AdapterDefinition>>;
|
|
38
48
|
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/lib/adapters/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,MAAM,MAAM,aAAa,GAAG,CAAC,aAAa,EAAE,MAAM,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAElF;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,cAAc,EAAE,SAAS,MAAM,EAAE,EACjC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAgB5C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,GAAG,CAAC,CAAC,OAAO,CAa9F;AAaD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAQhE;AAED
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/lib/adapters/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,EAA+B,KAAK,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG5F,MAAM,MAAM,aAAa,GAAG,CAAC,aAAa,EAAE,MAAM,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAElF;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,cAAc,EAAE,SAAS,MAAM,EAAE,EACjC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAgB5C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,GAAG,CAAC,CAAC,OAAO,CAa9F;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,EAC/C,UAAU,EAAE,SAAS,kBAAkB,EAAE,GACxC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAWnC;AAaD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAQhE;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAGqB,CAAC"}
|
|
@@ -13,6 +13,8 @@ import { __rewriteRelativeImportExtension } from "tslib";
|
|
|
13
13
|
import { readdirSync } from "node:fs";
|
|
14
14
|
import path from "node:path";
|
|
15
15
|
import { z } from "zod";
|
|
16
|
+
import { discoverTaskSourceManifests } from "./shell/discovery.js";
|
|
17
|
+
import { manifestAdapter } from "./shell/manifestAdapter.js";
|
|
16
18
|
/**
|
|
17
19
|
* Pure logic: given a list of subdirectory names and an async loader, build a
|
|
18
20
|
* `kind → AdapterDefinition` registry. Enforces directory-name === kind and
|
|
@@ -58,6 +60,23 @@ export function buildSourceConfigSchema(registry) {
|
|
|
58
60
|
// — semantically equivalent here because each kind has a unique literal.
|
|
59
61
|
return z.union([first, second, ...rest]);
|
|
60
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Fold discovered manifest sources into a code-adapter registry. Each becomes
|
|
65
|
+
* an adapter keyed by its manifest name. A manifest may not shadow a built-in
|
|
66
|
+
* code-adapter kind (`linear`, `shell`, `todo-txt`) - those are reserved, so a
|
|
67
|
+
* collision is a hard error. Manifest-vs-manifest precedence (user over
|
|
68
|
+
* package) is already resolved by discovery, so `discovered` has no duplicates.
|
|
69
|
+
*/
|
|
70
|
+
export function mergeManifestAdapters(codeRegistry, discovered) {
|
|
71
|
+
const merged = { ...codeRegistry };
|
|
72
|
+
for (const { manifest, manifestDir, origin } of discovered) {
|
|
73
|
+
if (codeRegistry[manifest.name]) {
|
|
74
|
+
throw new Error(`Task source "${manifest.name}" collides with the built-in "${manifest.name}" adapter. Rename the source manifest.`);
|
|
75
|
+
}
|
|
76
|
+
merged[manifest.name] = manifestAdapter(manifest, manifestDir, origin);
|
|
77
|
+
}
|
|
78
|
+
return merged;
|
|
79
|
+
}
|
|
61
80
|
const here = import.meta.dirname;
|
|
62
81
|
async function defaultImportLoader(directoryName) {
|
|
63
82
|
// Resolve relative to this module's directory. tsx maps `.js` → `.ts` in dev;
|
|
@@ -77,6 +96,7 @@ export function listAdapterDirectories(baseDir) {
|
|
|
77
96
|
return names;
|
|
78
97
|
}
|
|
79
98
|
/**
|
|
80
|
-
* Production registry.
|
|
99
|
+
* Production registry. Scans `src/lib/adapters/` for code adapters, then folds
|
|
100
|
+
* in the manifest sources discovered under the package + user task-sources roots.
|
|
81
101
|
*/
|
|
82
|
-
export const adapterRegistry = buildRegistry(listAdapterDirectories(here), defaultImportLoader);
|
|
102
|
+
export const adapterRegistry = buildRegistry(listAdapterDirectories(here), defaultImportLoader).then((codeRegistry) => mergeManifestAdapters(codeRegistry, discoverTaskSourceManifests()));
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Discover task-source manifests from two roots: the sources bundled inside
|
|
3
|
+
* this package (`<pkg>/task-sources`) and the user-installed sources under
|
|
4
|
+
* `~/.config/groundcrew/task-sources`. Each `<dir>/source.json` is validated
|
|
5
|
+
* and indexed by manifest name; a later root overrides an earlier one on a
|
|
6
|
+
* name collision (user over package), recording a warning. The registry
|
|
7
|
+
* (`../registry.ts`) turns each result into an enable-by-kind adapter.
|
|
8
|
+
*/
|
|
9
|
+
import { type SourceManifest } from "./manifest.ts";
|
|
10
|
+
type ManifestOrigin = "package" | "user";
|
|
11
|
+
export interface DiscoveredManifest {
|
|
12
|
+
manifest: SourceManifest;
|
|
13
|
+
manifestDir: string;
|
|
14
|
+
origin: ManifestOrigin;
|
|
15
|
+
}
|
|
16
|
+
export interface ManifestRoot {
|
|
17
|
+
dir: string;
|
|
18
|
+
origin: ManifestOrigin;
|
|
19
|
+
}
|
|
20
|
+
export interface DiscoveryResult {
|
|
21
|
+
manifests: DiscoveredManifest[];
|
|
22
|
+
warnings: string[];
|
|
23
|
+
}
|
|
24
|
+
export declare function discoverFromRoots(roots: readonly ManifestRoot[]): DiscoveryResult;
|
|
25
|
+
export declare function discoverTaskSourceManifests(): DiscoveredManifest[];
|
|
26
|
+
/**
|
|
27
|
+
* Look up a single discovered manifest by name (the enable-by-kind `kind`).
|
|
28
|
+
* Manifest-only: a built-in code adapter (`linear`, `todo-txt`) has no manifest,
|
|
29
|
+
* so this returns `undefined` for those kinds. Part of the public discovery API
|
|
30
|
+
* so crew-config can read a source's install-time hints (prerequisites,
|
|
31
|
+
* secrets) without re-scanning the roots itself.
|
|
32
|
+
*
|
|
33
|
+
* This reads the discovery roots fresh on each call. Prefer
|
|
34
|
+
* `discoverTaskSourceManifests()` when looking up multiple names in one flow so
|
|
35
|
+
* callers only pay the filesystem scan once.
|
|
36
|
+
*/
|
|
37
|
+
export declare function getTaskSourceManifest(name: string): SourceManifest | undefined;
|
|
38
|
+
export {};
|
|
39
|
+
//# sourceMappingURL=discovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/shell/discovery.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAE1E,KAAK,cAAc,GAAG,SAAS,GAAG,MAAM,CAAC;AAEzC,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,cAAc,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,kBAAkB,EAAE,CAAC;IAChC,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AA2BD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,GAAG,eAAe,CAoCjF;AAED,wBAAgB,2BAA2B,IAAI,kBAAkB,EAAE,CASlE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAG9E"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Discover task-source manifests from two roots: the sources bundled inside
|
|
3
|
+
* this package (`<pkg>/task-sources`) and the user-installed sources under
|
|
4
|
+
* `~/.config/groundcrew/task-sources`. Each `<dir>/source.json` is validated
|
|
5
|
+
* and indexed by manifest name; a later root overrides an earlier one on a
|
|
6
|
+
* name collision (user over package), recording a warning. The registry
|
|
7
|
+
* (`../registry.ts`) turns each result into an enable-by-kind adapter.
|
|
8
|
+
*/
|
|
9
|
+
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
10
|
+
import path from "node:path";
|
|
11
|
+
import { writeError } from "../../util.js";
|
|
12
|
+
import { xdgConfigPath } from "../../xdg.js";
|
|
13
|
+
import { describeFileError, isFileErrorCode } from "../todo-txt/fileErrors.js";
|
|
14
|
+
import { sourceManifestSchema } from "./manifest.js";
|
|
15
|
+
/** Sources bundled with this package, next to the built output in dev and prod. */
|
|
16
|
+
const PACKAGE_TASK_SOURCES_ROOT = path.resolve(import.meta.dirname, "../../../../task-sources");
|
|
17
|
+
/** Sources any external installer drops into the groundcrew config dir. */
|
|
18
|
+
function userTaskSourcesRoot() {
|
|
19
|
+
return xdgConfigPath("groundcrew", "task-sources");
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Read a root's directory entries, treating an absent or non-directory root as
|
|
23
|
+
* empty. A task-sources root is optional (a user may never install one, and it
|
|
24
|
+
* can be torn down mid-run), so "not a readable directory" yields no sources
|
|
25
|
+
* rather than crashing discovery. Any other fault (e.g. EACCES) is re-raised.
|
|
26
|
+
*/
|
|
27
|
+
function readRootEntries(dir) {
|
|
28
|
+
try {
|
|
29
|
+
return readdirSync(dir, { withFileTypes: true });
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
if (isFileErrorCode(error, "ENOENT") || isFileErrorCode(error, "ENOTDIR")) {
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
35
|
+
throw error;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export function discoverFromRoots(roots) {
|
|
39
|
+
const byName = new Map();
|
|
40
|
+
const warnings = [];
|
|
41
|
+
for (const root of roots) {
|
|
42
|
+
for (const entry of readRootEntries(root.dir)) {
|
|
43
|
+
if (!entry.isDirectory()) {
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
const manifestDir = path.join(root.dir, entry.name);
|
|
47
|
+
const manifestPath = path.join(manifestDir, "source.json");
|
|
48
|
+
if (!existsSync(manifestPath)) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
let manifest;
|
|
52
|
+
try {
|
|
53
|
+
manifest = sourceManifestSchema.parse(JSON.parse(readFileSync(manifestPath, "utf8")));
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
// One malformed source.json must not take down the whole registry: skip
|
|
57
|
+
// this source and warn, so every other adapter still loads.
|
|
58
|
+
warnings.push(`Ignoring invalid task source manifest at ${manifestPath}: ${describeFileError(error)}.`);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
const previous = byName.get(manifest.name);
|
|
62
|
+
if (previous) {
|
|
63
|
+
warnings.push(`Task source "${manifest.name}" from ${manifestDir} overrides the ${previous.origin} source at ${previous.manifestDir}.`);
|
|
64
|
+
}
|
|
65
|
+
byName.set(manifest.name, { manifest, manifestDir, origin: root.origin });
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return { manifests: [...byName.values()], warnings };
|
|
69
|
+
}
|
|
70
|
+
export function discoverTaskSourceManifests() {
|
|
71
|
+
const { manifests, warnings } = discoverFromRoots([
|
|
72
|
+
{ dir: PACKAGE_TASK_SOURCES_ROOT, origin: "package" },
|
|
73
|
+
{ dir: userTaskSourcesRoot(), origin: "user" },
|
|
74
|
+
]);
|
|
75
|
+
for (const warning of warnings) {
|
|
76
|
+
writeError(warning);
|
|
77
|
+
}
|
|
78
|
+
return manifests;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Look up a single discovered manifest by name (the enable-by-kind `kind`).
|
|
82
|
+
* Manifest-only: a built-in code adapter (`linear`, `todo-txt`) has no manifest,
|
|
83
|
+
* so this returns `undefined` for those kinds. Part of the public discovery API
|
|
84
|
+
* so crew-config can read a source's install-time hints (prerequisites,
|
|
85
|
+
* secrets) without re-scanning the roots itself.
|
|
86
|
+
*
|
|
87
|
+
* This reads the discovery roots fresh on each call. Prefer
|
|
88
|
+
* `discoverTaskSourceManifests()` when looking up multiple names in one flow so
|
|
89
|
+
* callers only pay the filesystem scan once.
|
|
90
|
+
*/
|
|
91
|
+
export function getTaskSourceManifest(name) {
|
|
92
|
+
return discoverTaskSourceManifests().find((discovered) => discovered.manifest.name === name)
|
|
93
|
+
?.manifest;
|
|
94
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/shell/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAGpE,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAEvD,QAAA,MAAM,UAAU,EAAE,iBAAiB,CAAC,OAAO,wBAAwB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/shell/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAGpE,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAEvD,QAAA,MAAM,UAAU,EAAE,iBAAiB,CAAC,OAAO,wBAAwB,CAUlE,CAAC;eAEa,UAAU"}
|
|
@@ -4,5 +4,11 @@ const definition = {
|
|
|
4
4
|
kind: "shell",
|
|
5
5
|
configSchema: shellAdapterConfigSchema,
|
|
6
6
|
create: createShellTaskSource,
|
|
7
|
+
meta: {
|
|
8
|
+
description: "Bring-your-own task source wired through shell command templates.",
|
|
9
|
+
// The generic escape hatch, not an installable source: excluded from the catalog.
|
|
10
|
+
template: true,
|
|
11
|
+
origin: "builtin",
|
|
12
|
+
},
|
|
7
13
|
};
|
|
8
14
|
export default definition;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Idempotent materialization of a task source's script files. Copies each
|
|
3
|
+
* `files[]` entry from the manifest's directory into `installDir` when the destination is
|
|
4
|
+
* missing or its bytes differ, then marks it executable. A manifest with no
|
|
5
|
+
* `files` installs nothing (the source is backed by a binary already on PATH).
|
|
6
|
+
* Never writes secrets - prerequisites and secrets stay the user's job.
|
|
7
|
+
*/
|
|
8
|
+
import type { SourceManifest } from "./manifest.ts";
|
|
9
|
+
export interface InstallShellSourceOptions {
|
|
10
|
+
manifest: SourceManifest;
|
|
11
|
+
manifestDir: string;
|
|
12
|
+
}
|
|
13
|
+
export interface InstalledShellSource {
|
|
14
|
+
installDir: string;
|
|
15
|
+
scriptPaths: string[];
|
|
16
|
+
}
|
|
17
|
+
export declare function installShellSource(options: InstallShellSourceOptions): InstalledShellSource;
|
|
18
|
+
//# sourceMappingURL=install.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/shell/install.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,cAAc,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,yBAAyB,GAAG,oBAAoB,CA8B3F"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Idempotent materialization of a task source's script files. Copies each
|
|
3
|
+
* `files[]` entry from the manifest's directory into `installDir` when the destination is
|
|
4
|
+
* missing or its bytes differ, then marks it executable. A manifest with no
|
|
5
|
+
* `files` installs nothing (the source is backed by a binary already on PATH).
|
|
6
|
+
* Never writes secrets - prerequisites and secrets stay the user's job.
|
|
7
|
+
*/
|
|
8
|
+
import { chmodSync, copyFileSync, existsSync, mkdirSync, readFileSync } from "node:fs";
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
import { expandHome } from "../../paths.js";
|
|
11
|
+
export function installShellSource(options) {
|
|
12
|
+
const { manifest, manifestDir } = options;
|
|
13
|
+
const installDir = expandHome(manifest.installDir);
|
|
14
|
+
const scriptPaths = [];
|
|
15
|
+
if (manifest.files.length > 0) {
|
|
16
|
+
mkdirSync(installDir, { recursive: true });
|
|
17
|
+
}
|
|
18
|
+
for (const file of manifest.files) {
|
|
19
|
+
const source = path.join(manifestDir, file);
|
|
20
|
+
const dest = path.join(installDir, file);
|
|
21
|
+
// Reject a files[] entry that escapes installDir (e.g. "../../.zshrc").
|
|
22
|
+
// Manifests are only semi-trusted, and each dest is made executable, so a
|
|
23
|
+
// traversal would let a source write over arbitrary files.
|
|
24
|
+
const relativeDest = path.relative(installDir, dest);
|
|
25
|
+
if (relativeDest === ".." || relativeDest.startsWith(`..${path.sep}`)) {
|
|
26
|
+
throw new Error(`Task source "${manifest.name}" lists file "${file}" that escapes its install directory "${installDir}".`);
|
|
27
|
+
}
|
|
28
|
+
mkdirSync(path.dirname(dest), { recursive: true });
|
|
29
|
+
if (!existsSync(dest) || readFileSync(dest).compare(readFileSync(source)) !== 0) {
|
|
30
|
+
copyFileSync(source, dest);
|
|
31
|
+
}
|
|
32
|
+
chmodSync(dest, 0o755);
|
|
33
|
+
scriptPaths.push(dest);
|
|
34
|
+
}
|
|
35
|
+
return { installDir, scriptPaths };
|
|
36
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `SourceManifest` describes a packaged task source's `source.json` (for
|
|
3
|
+
* example `task-sources/jira/source.json`). It is the install-time contract
|
|
4
|
+
* between whoever ships a source (groundcrew itself, or an external installer
|
|
5
|
+
* that drops a bundle into `~/.config/groundcrew/task-sources`) and groundcrew,
|
|
6
|
+
* which discovers manifests and exposes each as an enable-by-kind adapter.
|
|
7
|
+
*
|
|
8
|
+
* Deliberately separate from `ShellAdapterConfig` (the runtime config block in
|
|
9
|
+
* `./schema.ts`): the manifest carries install-only fields (`installDir`,
|
|
10
|
+
* `files`, `prerequisites`, `secrets`) and command templates whose script paths
|
|
11
|
+
* are not yet installed. `shellConfigFromManifest` (see `./manifestAdapter.ts`)
|
|
12
|
+
* bridges the two once the scripts are materialized.
|
|
13
|
+
*/
|
|
14
|
+
import { z } from "zod";
|
|
15
|
+
/**
|
|
16
|
+
* Per-command timeouts in milliseconds. Shared with the override schema in
|
|
17
|
+
* `./manifestAdapter.ts` so a `{ kind }` entry can override manifest timeouts.
|
|
18
|
+
*/
|
|
19
|
+
export declare const manifestTimeoutsSchema: z.ZodObject<{
|
|
20
|
+
verify: z.ZodOptional<z.ZodNumber>;
|
|
21
|
+
listTasks: z.ZodOptional<z.ZodNumber>;
|
|
22
|
+
getTask: z.ZodOptional<z.ZodNumber>;
|
|
23
|
+
markInProgress: z.ZodOptional<z.ZodNumber>;
|
|
24
|
+
markInReview: z.ZodOptional<z.ZodNumber>;
|
|
25
|
+
markDone: z.ZodOptional<z.ZodNumber>;
|
|
26
|
+
createTask: z.ZodOptional<z.ZodNumber>;
|
|
27
|
+
validate: z.ZodOptional<z.ZodNumber>;
|
|
28
|
+
}, z.core.$strict>;
|
|
29
|
+
export declare const sourceManifestSchema: z.ZodObject<{
|
|
30
|
+
name: z.ZodString;
|
|
31
|
+
kind: z.ZodLiteral<"shell">;
|
|
32
|
+
description: z.ZodString;
|
|
33
|
+
installDir: z.ZodString;
|
|
34
|
+
files: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
35
|
+
prerequisites: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
36
|
+
bin: z.ZodString;
|
|
37
|
+
install: z.ZodOptional<z.ZodString>;
|
|
38
|
+
setup: z.ZodOptional<z.ZodString>;
|
|
39
|
+
}, z.core.$strict>>>;
|
|
40
|
+
secrets: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
41
|
+
env: z.ZodString;
|
|
42
|
+
file: z.ZodString;
|
|
43
|
+
mode: z.ZodOptional<z.ZodString>;
|
|
44
|
+
url: z.ZodOptional<z.ZodString>;
|
|
45
|
+
}, z.core.$strict>>>;
|
|
46
|
+
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
47
|
+
commands: z.ZodObject<{
|
|
48
|
+
verify: z.ZodOptional<z.ZodString>;
|
|
49
|
+
listTasks: z.ZodString;
|
|
50
|
+
getTask: z.ZodOptional<z.ZodString>;
|
|
51
|
+
markInProgress: z.ZodOptional<z.ZodString>;
|
|
52
|
+
markInReview: z.ZodOptional<z.ZodString>;
|
|
53
|
+
markDone: z.ZodOptional<z.ZodString>;
|
|
54
|
+
createTask: z.ZodOptional<z.ZodString>;
|
|
55
|
+
validate: z.ZodOptional<z.ZodString>;
|
|
56
|
+
}, z.core.$strict>;
|
|
57
|
+
timeouts: z.ZodOptional<z.ZodObject<{
|
|
58
|
+
verify: z.ZodOptional<z.ZodNumber>;
|
|
59
|
+
listTasks: z.ZodOptional<z.ZodNumber>;
|
|
60
|
+
getTask: z.ZodOptional<z.ZodNumber>;
|
|
61
|
+
markInProgress: z.ZodOptional<z.ZodNumber>;
|
|
62
|
+
markInReview: z.ZodOptional<z.ZodNumber>;
|
|
63
|
+
markDone: z.ZodOptional<z.ZodNumber>;
|
|
64
|
+
createTask: z.ZodOptional<z.ZodNumber>;
|
|
65
|
+
validate: z.ZodOptional<z.ZodNumber>;
|
|
66
|
+
}, z.core.$strict>>;
|
|
67
|
+
}, z.core.$strict>;
|
|
68
|
+
export type SourceManifest = z.infer<typeof sourceManifestSchema>;
|
|
69
|
+
//# sourceMappingURL=manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/shell/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA0BxB;;;GAGG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;kBASjC,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAa/B,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `SourceManifest` describes a packaged task source's `source.json` (for
|
|
3
|
+
* example `task-sources/jira/source.json`). It is the install-time contract
|
|
4
|
+
* between whoever ships a source (groundcrew itself, or an external installer
|
|
5
|
+
* that drops a bundle into `~/.config/groundcrew/task-sources`) and groundcrew,
|
|
6
|
+
* which discovers manifests and exposes each as an enable-by-kind adapter.
|
|
7
|
+
*
|
|
8
|
+
* Deliberately separate from `ShellAdapterConfig` (the runtime config block in
|
|
9
|
+
* `./schema.ts`): the manifest carries install-only fields (`installDir`,
|
|
10
|
+
* `files`, `prerequisites`, `secrets`) and command templates whose script paths
|
|
11
|
+
* are not yet installed. `shellConfigFromManifest` (see `./manifestAdapter.ts`)
|
|
12
|
+
* bridges the two once the scripts are materialized.
|
|
13
|
+
*/
|
|
14
|
+
import { z } from "zod";
|
|
15
|
+
const prerequisiteSchema = z.strictObject({
|
|
16
|
+
bin: z.string().min(1),
|
|
17
|
+
install: z.string().optional(),
|
|
18
|
+
setup: z.string().optional(),
|
|
19
|
+
});
|
|
20
|
+
const secretSchema = z.strictObject({
|
|
21
|
+
env: z.string().min(1),
|
|
22
|
+
file: z.string().min(1),
|
|
23
|
+
mode: z.string().optional(),
|
|
24
|
+
url: z.string().optional(),
|
|
25
|
+
});
|
|
26
|
+
const commandsSchema = z.strictObject({
|
|
27
|
+
verify: z.string().optional(),
|
|
28
|
+
listTasks: z.string(),
|
|
29
|
+
getTask: z.string().optional(),
|
|
30
|
+
markInProgress: z.string().optional(),
|
|
31
|
+
markInReview: z.string().optional(),
|
|
32
|
+
markDone: z.string().optional(),
|
|
33
|
+
createTask: z.string().optional(),
|
|
34
|
+
validate: z.string().optional(),
|
|
35
|
+
});
|
|
36
|
+
/**
|
|
37
|
+
* Per-command timeouts in milliseconds. Shared with the override schema in
|
|
38
|
+
* `./manifestAdapter.ts` so a `{ kind }` entry can override manifest timeouts.
|
|
39
|
+
*/
|
|
40
|
+
export const manifestTimeoutsSchema = z.strictObject({
|
|
41
|
+
verify: z.number().int().positive().optional(),
|
|
42
|
+
listTasks: z.number().int().positive().optional(),
|
|
43
|
+
getTask: z.number().int().positive().optional(),
|
|
44
|
+
markInProgress: z.number().int().positive().optional(),
|
|
45
|
+
markInReview: z.number().int().positive().optional(),
|
|
46
|
+
markDone: z.number().int().positive().optional(),
|
|
47
|
+
createTask: z.number().int().positive().optional(),
|
|
48
|
+
validate: z.number().int().positive().optional(),
|
|
49
|
+
});
|
|
50
|
+
export const sourceManifestSchema = z.strictObject({
|
|
51
|
+
name: z
|
|
52
|
+
.string()
|
|
53
|
+
.regex(/^[a-z][a-z0-9-]*$/, "name must be kebab-case (lowercase letters, digits, hyphens)"),
|
|
54
|
+
kind: z.literal("shell"),
|
|
55
|
+
description: z.string(),
|
|
56
|
+
installDir: z.string().min(1),
|
|
57
|
+
files: z.array(z.string().min(1)).default([]),
|
|
58
|
+
prerequisites: z.array(prerequisiteSchema).optional(),
|
|
59
|
+
secrets: z.array(secretSchema).optional(),
|
|
60
|
+
env: z.record(z.string(), z.string()).optional(),
|
|
61
|
+
commands: commandsSchema,
|
|
62
|
+
timeouts: manifestTimeoutsSchema.optional(),
|
|
63
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bridges a discovered `SourceManifest` to the shell adapter runtime so a
|
|
3
|
+
* packaged/installed source is enabled with `{ kind: "<name>" }` alone. The
|
|
4
|
+
* synthetic adapter's `kind` is the manifest name; its config schema accepts
|
|
5
|
+
* light overrides (`name`, `env`, `timeouts`, `enabled`) that merge over the
|
|
6
|
+
* manifest defaults. Full command control stays with the generic `kind:"shell"`
|
|
7
|
+
* adapter. `create` materializes the scripts (idempotent) before building the
|
|
8
|
+
* TaskSource, so enabling a source is also what installs it.
|
|
9
|
+
*/
|
|
10
|
+
import type { AdapterDefinition, AdapterMeta, AdapterOrigin } from "../../adapterDefinition.ts";
|
|
11
|
+
import { type SourceManifest } from "./manifest.ts";
|
|
12
|
+
import type { ShellAdapterConfig } from "./schema.ts";
|
|
13
|
+
export interface ManifestOverrides {
|
|
14
|
+
name?: string | undefined;
|
|
15
|
+
env?: Record<string, string> | undefined;
|
|
16
|
+
timeouts?: ShellAdapterConfig["timeouts"] | undefined;
|
|
17
|
+
}
|
|
18
|
+
export declare function shellConfigFromManifest(manifest: SourceManifest, overrides?: ManifestOverrides): ShellAdapterConfig;
|
|
19
|
+
/**
|
|
20
|
+
* Descriptive metadata for the unified catalog, derived from the manifest. A
|
|
21
|
+
* source `requiresCredentials` when it declares any `secrets`; `origin` is where
|
|
22
|
+
* discovery found it (bundled `package` vs. user-installed `user`).
|
|
23
|
+
*/
|
|
24
|
+
export declare function manifestMeta(manifest: SourceManifest, origin: AdapterOrigin): AdapterMeta;
|
|
25
|
+
export declare function manifestAdapter(manifest: SourceManifest, manifestDir: string, origin: AdapterOrigin): AdapterDefinition;
|
|
26
|
+
//# sourceMappingURL=manifestAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifestAdapter.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/shell/manifestAdapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAEV,iBAAiB,EACjB,WAAW,EACX,aAAa,EACd,MAAM,4BAA4B,CAAC;AAKpC,OAAO,EAA0B,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAC5E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtD,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,EAAE,kBAAkB,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC;CACvD;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,cAAc,EACxB,SAAS,GAAE,iBAAsB,GAChC,kBAAkB,CAUpB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,cAAc,EAAE,MAAM,EAAE,aAAa,GAAG,WAAW,CAMzF;AAED,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,cAAc,EACxB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,aAAa,GACpB,iBAAiB,CA+BnB"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bridges a discovered `SourceManifest` to the shell adapter runtime so a
|
|
3
|
+
* packaged/installed source is enabled with `{ kind: "<name>" }` alone. The
|
|
4
|
+
* synthetic adapter's `kind` is the manifest name; its config schema accepts
|
|
5
|
+
* light overrides (`name`, `env`, `timeouts`, `enabled`) that merge over the
|
|
6
|
+
* manifest defaults. Full command control stays with the generic `kind:"shell"`
|
|
7
|
+
* adapter. `create` materializes the scripts (idempotent) before building the
|
|
8
|
+
* TaskSource, so enabling a source is also what installs it.
|
|
9
|
+
*/
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
import { createShellTaskSource } from "./factory.js";
|
|
12
|
+
import { installShellSource } from "./install.js";
|
|
13
|
+
import { manifestTimeoutsSchema } from "./manifest.js";
|
|
14
|
+
export function shellConfigFromManifest(manifest, overrides = {}) {
|
|
15
|
+
const env = { ...manifest.env, ...overrides.env };
|
|
16
|
+
const timeouts = overrides.timeouts ?? manifest.timeouts;
|
|
17
|
+
return {
|
|
18
|
+
kind: "shell",
|
|
19
|
+
name: overrides.name ?? manifest.name,
|
|
20
|
+
commands: manifest.commands,
|
|
21
|
+
...(Object.keys(env).length > 0 ? { env } : {}),
|
|
22
|
+
...(timeouts ? { timeouts } : {}),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Descriptive metadata for the unified catalog, derived from the manifest. A
|
|
27
|
+
* source `requiresCredentials` when it declares any `secrets`; `origin` is where
|
|
28
|
+
* discovery found it (bundled `package` vs. user-installed `user`).
|
|
29
|
+
*/
|
|
30
|
+
export function manifestMeta(manifest, origin) {
|
|
31
|
+
return {
|
|
32
|
+
description: manifest.description,
|
|
33
|
+
requiresCredentials: (manifest.secrets?.length ?? 0) > 0,
|
|
34
|
+
origin,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export function manifestAdapter(manifest, manifestDir, origin) {
|
|
38
|
+
const configSchema = z.strictObject({
|
|
39
|
+
kind: z.literal(manifest.name),
|
|
40
|
+
name: z
|
|
41
|
+
.string()
|
|
42
|
+
.regex(/^[a-z][a-z0-9-]*$/, "name must be kebab-case (lowercase letters, digits, hyphens)")
|
|
43
|
+
.optional(),
|
|
44
|
+
env: z.record(z.string(), z.string()).optional(),
|
|
45
|
+
timeouts: manifestTimeoutsSchema.optional(),
|
|
46
|
+
enabled: z.boolean().optional(),
|
|
47
|
+
});
|
|
48
|
+
return {
|
|
49
|
+
kind: manifest.name,
|
|
50
|
+
configSchema,
|
|
51
|
+
// `config` arrives already validated from buildSourcesWith; re-parse to
|
|
52
|
+
// recover the typed overrides without an unsafe cast. Cheap and idempotent.
|
|
53
|
+
create: (config, context) => {
|
|
54
|
+
const overrides = configSchema.parse(config);
|
|
55
|
+
installShellSource({ manifest, manifestDir });
|
|
56
|
+
return createShellTaskSource(shellConfigFromManifest(manifest, {
|
|
57
|
+
name: overrides.name,
|
|
58
|
+
env: overrides.env,
|
|
59
|
+
timeouts: overrides.timeouts,
|
|
60
|
+
}), context);
|
|
61
|
+
},
|
|
62
|
+
meta: manifestMeta(manifest, origin),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/todo-txt/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAGpE,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAEzD,QAAA,MAAM,UAAU,EAAE,iBAAiB,CAAC,OAAO,0BAA0B,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/todo-txt/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAGpE,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAEzD,QAAA,MAAM,UAAU,EAAE,iBAAiB,CAAC,OAAO,0BAA0B,CAQpE,CAAC;eAEa,UAAU"}
|
|
@@ -4,5 +4,9 @@ const definition = {
|
|
|
4
4
|
kind: "todo-txt",
|
|
5
5
|
configSchema: todoTxtAdapterConfigSchema,
|
|
6
6
|
create: createTodoTxtTaskSource,
|
|
7
|
+
meta: {
|
|
8
|
+
description: "Track tasks from a local todo.txt file; no credentials required.",
|
|
9
|
+
origin: "builtin",
|
|
10
|
+
},
|
|
7
11
|
};
|
|
8
12
|
export default definition;
|
package/dist/lib/config.d.ts
CHANGED
|
@@ -2,13 +2,26 @@ import type { LinearAdapterConfig } from "./adapters/linear/schema.ts";
|
|
|
2
2
|
import type { ShellAdapterConfig } from "./adapters/shell/schema.ts";
|
|
3
3
|
import type { TodoTxtAdapterConfig } from "./adapters/todo-txt/schema.ts";
|
|
4
4
|
export { BUILD_SECRET_NAMES } from "./buildSecrets.ts";
|
|
5
|
+
/**
|
|
6
|
+
* Authoring shape for a manifest-backed (discovered) task source: enable by
|
|
7
|
+
* kind, with light overrides. The concrete per-source schema is built at
|
|
8
|
+
* runtime by `manifestAdapter` and validated at `buildSources` time, so the
|
|
9
|
+
* static type here is intentionally permissive.
|
|
10
|
+
*/
|
|
11
|
+
export interface ManifestSourceConfig {
|
|
12
|
+
kind: string;
|
|
13
|
+
name?: string;
|
|
14
|
+
env?: Record<string, string>;
|
|
15
|
+
timeouts?: ShellAdapterConfig["timeouts"];
|
|
16
|
+
enabled?: boolean;
|
|
17
|
+
}
|
|
5
18
|
/**
|
|
6
19
|
* Discriminated union of all built-in adapter config shapes. Used at
|
|
7
20
|
* config-load time as the static type for `Config.sources[]` and
|
|
8
21
|
* `ResolvedConfig.sources[]`. The runtime Zod validation lives in each
|
|
9
22
|
* adapter's `schema.ts` and runs at `buildSources` time, not here.
|
|
10
23
|
*/
|
|
11
|
-
export type SourceConfig = LinearAdapterConfig | ShellAdapterConfig | TodoTxtAdapterConfig;
|
|
24
|
+
export type SourceConfig = LinearAdapterConfig | ShellAdapterConfig | TodoTxtAdapterConfig | ManifestSourceConfig;
|
|
12
25
|
export interface HookCommands {
|
|
13
26
|
prepareWorktree?: string;
|
|
14
27
|
}
|
package/dist/lib/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAO1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD;;;;;GAKG;AACH,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sourceCapabilities.d.ts","sourceRoot":"","sources":["../../src/lib/sourceCapabilities.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sourceCapabilities.d.ts","sourceRoot":"","sources":["../../src/lib/sourceCapabilities.ts"],"names":[],"mappings":"AAMA,UAAU,kBAAkB;IAC1B,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;IACxB,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,kBAAkB,CAAC;CAClC;AAgGD,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,aAAa,CAiB3D;AAED,wBAAgB,sBAAsB,CAAC,UAAU,EAAE;IACjD,UAAU,EAAE,SAAS,OAAO,EAAE,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CASV;AAED,wBAAgB,6BAA6B,CAAC,UAAU,EAAE;IACxD,UAAU,EAAE,SAAS,OAAO,EAAE,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAcV"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { discoverTaskSourceManifests } from "./adapters/shell/discovery.js";
|
|
2
3
|
import { shellAdapterConfigSchema } from "./adapters/shell/schema.js";
|
|
4
|
+
let cachedManifestCapabilitiesByKind;
|
|
3
5
|
const nameShape = z.looseObject({ name: z.string().optional() });
|
|
4
6
|
const kindShape = z.object({ kind: z.string() });
|
|
5
7
|
const LINEAR_CAPABILITIES = {
|
|
@@ -36,6 +38,34 @@ function shellCapabilities(raw) {
|
|
|
36
38
|
validate: commands.validate !== undefined,
|
|
37
39
|
};
|
|
38
40
|
}
|
|
41
|
+
function manifestCapabilities(arguments_) {
|
|
42
|
+
const { manifest } = arguments_;
|
|
43
|
+
const { commands } = manifest;
|
|
44
|
+
return {
|
|
45
|
+
verify: commands.verify !== undefined,
|
|
46
|
+
listTasks: true,
|
|
47
|
+
getTask: commands.getTask !== undefined,
|
|
48
|
+
createTask: commands.createTask !== undefined,
|
|
49
|
+
markInProgress: commands.markInProgress !== undefined,
|
|
50
|
+
markInReview: commands.markInReview !== undefined,
|
|
51
|
+
markDone: commands.markDone !== undefined,
|
|
52
|
+
validate: commands.validate !== undefined,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function getManifestCapabilitiesByKind() {
|
|
56
|
+
if (cachedManifestCapabilitiesByKind === undefined) {
|
|
57
|
+
const capabilitiesByKind = new Map();
|
|
58
|
+
for (const { manifest } of discoverTaskSourceManifests()) {
|
|
59
|
+
capabilitiesByKind.set(manifest.name, manifestCapabilities({ manifest }));
|
|
60
|
+
}
|
|
61
|
+
cachedManifestCapabilitiesByKind = capabilitiesByKind;
|
|
62
|
+
}
|
|
63
|
+
return cachedManifestCapabilitiesByKind;
|
|
64
|
+
}
|
|
65
|
+
function manifestCapabilitiesForKind(arguments_) {
|
|
66
|
+
const { kind } = arguments_;
|
|
67
|
+
return getManifestCapabilitiesByKind().get(kind);
|
|
68
|
+
}
|
|
39
69
|
const TODO_TXT_CAPABILITIES = {
|
|
40
70
|
verify: true,
|
|
41
71
|
listTasks: true,
|
|
@@ -61,7 +91,7 @@ export function summarizeSource(raw) {
|
|
|
61
91
|
capabilities = TODO_TXT_CAPABILITIES;
|
|
62
92
|
}
|
|
63
93
|
else {
|
|
64
|
-
capabilities = UNKNOWN_KIND_CAPABILITIES;
|
|
94
|
+
capabilities = manifestCapabilitiesForKind({ kind }) ?? UNKNOWN_KIND_CAPABILITIES;
|
|
65
95
|
}
|
|
66
96
|
return { name: sourceName, kind, capabilities };
|
|
67
97
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clipboard-health/groundcrew",
|
|
3
|
-
"version": "4.46.
|
|
3
|
+
"version": "4.46.4",
|
|
4
4
|
"description": "Linear-driven orchestrator that launches AI coding agents in git worktrees, with workspace lifecycle and usage tracking.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|
|
@@ -71,34 +71,34 @@
|
|
|
71
71
|
},
|
|
72
72
|
"dependencies": {
|
|
73
73
|
"@anthropic-ai/sandbox-runtime": "0.0.63",
|
|
74
|
-
"@clipboard-health/clearance": "1.
|
|
74
|
+
"@clipboard-health/clearance": "1.4.4",
|
|
75
75
|
"@linear/sdk": "88.0.0",
|
|
76
76
|
"cosmiconfig": "9.0.2",
|
|
77
77
|
"tslib": "2.8.1",
|
|
78
78
|
"zod": "4.4.3"
|
|
79
79
|
},
|
|
80
80
|
"devDependencies": {
|
|
81
|
-
"@clipboard-health/ai-rules": "2.
|
|
82
|
-
"@clipboard-health/oxlint-config": "1.12.
|
|
83
|
-
"@nx/js": "22.7.
|
|
81
|
+
"@clipboard-health/ai-rules": "2.34.0",
|
|
82
|
+
"@clipboard-health/oxlint-config": "1.12.6",
|
|
83
|
+
"@nx/js": "22.7.6",
|
|
84
84
|
"@tsconfig/node24": "24.0.4",
|
|
85
85
|
"@tsconfig/strictest": "2.0.8",
|
|
86
86
|
"@types/node": "25.9.4",
|
|
87
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
87
|
+
"@typescript/native-preview": "7.0.0-dev.20260703.1",
|
|
88
88
|
"@vitest/coverage-v8": "4.1.9",
|
|
89
89
|
"cspell": "10.0.1",
|
|
90
90
|
"dependency-cruiser": "18.0.0",
|
|
91
91
|
"husky": "9.1.7",
|
|
92
92
|
"jscpd": "5.0.11",
|
|
93
|
-
"knip": "6.
|
|
93
|
+
"knip": "6.24.0",
|
|
94
94
|
"lint-staged": "17.0.8",
|
|
95
95
|
"markdownlint-cli2": "0.22.1",
|
|
96
|
-
"nx": "22.7.
|
|
97
|
-
"oxfmt": "0.
|
|
98
|
-
"oxlint": "1.
|
|
96
|
+
"nx": "22.7.6",
|
|
97
|
+
"oxfmt": "0.57.0",
|
|
98
|
+
"oxlint": "1.72.0",
|
|
99
99
|
"oxlint-tsgolint": "0.23.0",
|
|
100
100
|
"syncpack": "15.3.2",
|
|
101
|
-
"vite": "8.
|
|
101
|
+
"vite": "8.1.3",
|
|
102
102
|
"vitest": "4.1.9"
|
|
103
103
|
},
|
|
104
104
|
"engines": {
|