@clipboard-health/groundcrew 4.2.1 → 4.2.2
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 +15 -25
- package/dist/commands/dispatcher.d.ts +2 -1
- package/dist/commands/dispatcher.d.ts.map +1 -1
- package/dist/commands/dispatcher.js +15 -3
- package/dist/lib/adapters/linear/fetch.d.ts +3 -3
- package/dist/lib/adapters/linear/fetch.d.ts.map +1 -1
- package/dist/lib/adapters/linear/fetch.js +8 -4
- package/dist/lib/ticketSource.d.ts +2 -2
- package/dist/lib/ticketSource.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
</p>
|
|
7
7
|
|
|
8
8
|
<p align="center">
|
|
9
|
-
Dispatch your
|
|
9
|
+
Dispatch your ticket backlog to AI coding agents. One git worktree per ticket, sandboxed by default.
|
|
10
10
|
</p>
|
|
11
11
|
|
|
12
12
|
<p align="center">
|
|
@@ -46,9 +46,9 @@ In Progress (state.type=started) — Add retry logic to the sync job
|
|
|
46
46
|
|
|
47
47
|
## Why
|
|
48
48
|
|
|
49
|
-
- **
|
|
49
|
+
- **Pluggable ticket sources.** Ships with a built-in Linear adapter (polls your API key viewer's `agent-*`-labeled issues, honors blockers); bring shell, Jira, or any source via `crew.config.ts`.
|
|
50
50
|
- **One worktree per ticket.** Agents work in parallel without stepping on each other.
|
|
51
|
-
- **Local-first sandboxing.** Safehouse on macOS, Docker Sandboxes on Linux, or an explicit `none` escape hatch.
|
|
51
|
+
- **Local-first sandboxing.** Safehouse on macOS, Docker Sandboxes on Linux/WSL, or an explicit `none` escape hatch.
|
|
52
52
|
- **Multi-agent.** Ships with `claude` and `codex`; bring your own CLI via `crew.config.ts`.
|
|
53
53
|
|
|
54
54
|
## Quickstart
|
|
@@ -94,28 +94,18 @@ crew cleanup <TICKET> # tear down every workt
|
|
|
94
94
|
crew upgrade [<version>] # reinstall crew globally through npm
|
|
95
95
|
```
|
|
96
96
|
|
|
97
|
-
|
|
97
|
+
## Manual repository bootstrap
|
|
98
98
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
Groundcrew no longer clones repositories for you. For each `workspace.knownRepositories` entry,
|
|
102
|
-
clone the repository into `workspace.projectDir` using the same relative path that appears in the
|
|
103
|
-
config. For an `OWNER/REPO` entry:
|
|
99
|
+
Groundcrew never clones repositories for you. Clone each `workspace.knownRepositories` entry into `workspace.projectDir` using the same relative path the config uses. For an `OWNER/REPO` entry:
|
|
104
100
|
|
|
105
101
|
```bash
|
|
106
102
|
PROJECT_DIR="$HOME/dev/c"
|
|
107
103
|
mkdir -p "$PROJECT_DIR/OWNER"
|
|
108
104
|
git clone git@github.com:OWNER/REPO.git "$PROJECT_DIR/OWNER/REPO"
|
|
105
|
+
# HTTPS works the same: git clone https://github.com/OWNER/REPO.git "$PROJECT_DIR/OWNER/REPO"
|
|
109
106
|
```
|
|
110
107
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
```bash
|
|
114
|
-
git clone https://github.com/OWNER/REPO.git "$PROJECT_DIR/OWNER/REPO"
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
Bare-name entries do not include an owner, so choose the correct remote URL yourself and clone it to
|
|
118
|
-
`$PROJECT_DIR/<name>`. `crew setup repos` now exits non-zero and points back to this section.
|
|
108
|
+
Bare-name entries have no owner, so pick the remote URL yourself and clone to `$PROJECT_DIR/<name>`.
|
|
119
109
|
|
|
120
110
|
## Configuration
|
|
121
111
|
|
|
@@ -144,7 +134,7 @@ Status classification uses Linear's workflow `state.type` (`unstarted`, `started
|
|
|
144
134
|
<details>
|
|
145
135
|
<summary>Config discovery</summary>
|
|
146
136
|
|
|
147
|
-
Resolution order: `GROUNDCREW_CONFIG` → cosmiconfig project-walk from cwd (any of `crew.config.{ts,mjs,js,json}`, `.crewrc{,.json,.ts}`, `.config/crew.config.{ts,json}`, `.config/crewrc{,.json}`) → `${XDG_CONFIG_HOME:-$HOME/.config}/groundcrew/crew.config.ts
|
|
137
|
+
Resolution order: `GROUNDCREW_CONFIG` → cosmiconfig project-walk from cwd (any of `crew.config.{ts,mjs,js,json}`, `.crewrc{,.json,.ts}`, `.config/crew.config.{ts,json}`, `.config/crewrc{,.json}`) → `${XDG_CONFIG_HOME:-$HOME/.config}/groundcrew/crew.config.ts`. The "Loaded config from …" line at startup tells you which won.
|
|
148
138
|
|
|
149
139
|
</details>
|
|
150
140
|
|
|
@@ -153,7 +143,7 @@ Resolution order: `GROUNDCREW_CONFIG` → cosmiconfig project-walk from cwd (any
|
|
|
153
143
|
|
|
154
144
|
| Key | Default | What it does |
|
|
155
145
|
| --------------------------------------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
156
|
-
| `sources` | `[]` | Additional pluggable ticket sources
|
|
146
|
+
| `sources` | `[]` | Additional pluggable ticket sources, dispatched alongside the built-in Linear adapter. Built-in kinds: `shell`, `linear`. |
|
|
157
147
|
| `git.remote` | `"origin"` | Remote used for `fetch` and as the worktree base ref. |
|
|
158
148
|
| `git.defaultBranch` | `"main"` | Branch fetched from `git.remote` and used as the worktree base. |
|
|
159
149
|
| `workspace.projectDir` | **required** | Parent dir for cloned repos and sibling ticket worktrees. |
|
|
@@ -235,7 +225,7 @@ Use `crew cleanup <TICKET>` to tear down stale worktrees and `crew resume <TICKE
|
|
|
235
225
|
|
|
236
226
|
## Doctor
|
|
237
227
|
|
|
238
|
-
`crew doctor` checks host prerequisites only: config validity, Linear
|
|
228
|
+
`crew doctor` checks host prerequisites only: config validity, ticket-source reachability (every configured source's `verify()`, including the built-in Linear adapter), required binaries on PATH, workspace backend availability, workspace.projectDir, local runner capability, and enabled model commands.
|
|
239
229
|
|
|
240
230
|
<details>
|
|
241
231
|
<summary>Sample ticket status output</summary>
|
|
@@ -269,7 +259,7 @@ In Progress (state.type=started) — Multi-event extractor: year inference can p
|
|
|
269
259
|
|
|
270
260
|
### `crew start <TICKET>`
|
|
271
261
|
|
|
272
|
-
Launches one ticket immediately, bypassing orchestrator eligibility. Use it to dispatch a specific ticket on demand — including unlabeled tickets that `crew run` ignores.
|
|
262
|
+
Launches one ticket immediately, bypassing orchestrator eligibility. Use it to dispatch a specific ticket on demand — including unlabeled tickets that `crew run` ignores.
|
|
273
263
|
|
|
274
264
|
```bash
|
|
275
265
|
crew start HRD-442
|
|
@@ -278,7 +268,7 @@ crew start HRD-442 --dry-run
|
|
|
278
268
|
|
|
279
269
|
### `crew stop <TICKET>`
|
|
280
270
|
|
|
281
|
-
Stops a live workspace pane while preserving the ticket worktree and branch. The manual pause button for cases where you need terminal capacity back, want to stop an agent that's going in the wrong direction, or need to inspect the diff before letting another agent continue.
|
|
271
|
+
Stops a live workspace pane while preserving the ticket worktree and branch. The manual pause button for cases where you need terminal capacity back, want to stop an agent that's going in the wrong direction, or need to inspect the diff before letting another agent continue.
|
|
282
272
|
|
|
283
273
|
```bash
|
|
284
274
|
crew stop HRD-442 --reason "wrong implementation direction"
|
|
@@ -368,7 +358,7 @@ To scaffold `.groundcrew/setup.sh` with a coding agent (Claude Code, Cursor, etc
|
|
|
368
358
|
|
|
369
359
|
## Pluggable ticket sources
|
|
370
360
|
|
|
371
|
-
`sources` declares extra ticket-system adapters.
|
|
361
|
+
`sources` declares extra ticket-system adapters. They're verified at `crew run` startup and dispatched alongside the built-in Linear adapter, so a shell, Jira, or local-plan integration feeds the same orchestration loop as Linear.
|
|
372
362
|
|
|
373
363
|
The built-in `shell` adapter runs command templates and reads JSON from stdout:
|
|
374
364
|
|
|
@@ -543,11 +533,11 @@ node --run crew -- doctor
|
|
|
543
533
|
node --run crew:op -- run --watch
|
|
544
534
|
```
|
|
545
535
|
|
|
546
|
-
Both forms discover config via cosmiconfig — project-walk from cwd for `crew.config.ts` and friends, then `${XDG_CONFIG_HOME:-$HOME/.config}/groundcrew/crew.config.ts
|
|
536
|
+
Both forms discover config via cosmiconfig — project-walk from cwd for `crew.config.ts` and friends, then `${XDG_CONFIG_HOME:-$HOME/.config}/groundcrew/crew.config.ts`. Set `GROUNDCREW_CONFIG` to point elsewhere. The `crew:op` wrapper additionally reads `${XDG_CONFIG_HOME:-$HOME/.config}/groundcrew/op.env` (1Password env-file with `op://` references resolved at launch).
|
|
547
537
|
|
|
548
538
|
Logs land in `${XDG_STATE_HOME:-$HOME/.local/state}/groundcrew/groundcrew.log` by default (override via `logging.file`).
|
|
549
539
|
|
|
550
|
-
Source edits in `src/**` are picked up on the next invocation. Requires Node ≥ 24
|
|
540
|
+
Source edits in `src/**` are picked up on the next invocation. Requires Node ≥ 24 (native `.ts` type stripping).
|
|
551
541
|
|
|
552
542
|
## License
|
|
553
543
|
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import type { Board } from "../lib/board.ts";
|
|
10
10
|
import type { ResolvedConfig } from "../lib/config.ts";
|
|
11
|
-
import { type BoardState } from "../lib/ticketSource.ts";
|
|
11
|
+
import { type BoardState, type Issue } from "../lib/ticketSource.ts";
|
|
12
12
|
import type { UsageByModel } from "../lib/usage.ts";
|
|
13
13
|
import type { WorktreeEntry } from "../lib/worktrees.ts";
|
|
14
14
|
interface DispatcherDeps {
|
|
@@ -32,5 +32,6 @@ export interface Dispatcher {
|
|
|
32
32
|
}): Promise<void>;
|
|
33
33
|
}
|
|
34
34
|
export declare function createDispatcher(deps: DispatcherDeps): Dispatcher;
|
|
35
|
+
export declare function formatActiveSlotList(active: readonly Issue[]): string;
|
|
35
36
|
export {};
|
|
36
37
|
//# sourceMappingURL=dispatcher.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/commands/dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EACL,KAAK,UAAU,
|
|
1
|
+
{"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/commands/dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EACL,KAAK,UAAU,EAGf,KAAK,KAAK,EAEX,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAGpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAWzD,UAAU,cAAc;IACtB,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,EAAE,KAAK,CAAC;CACd;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,UAAU,EAAE;QAClB,KAAK,EAAE,UAAU,CAAC;QAClB,eAAe,EAAE,SAAS,aAAa,EAAE,CAAC;QAC1C,+FAA+F;QAC/F,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;QACvD,MAAM,EAAE,OAAO,CAAC;QAChB,MAAM,CAAC,EAAE,WAAW,CAAC;QACrB;;;;WAIG;QACH,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnB;AAaD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,UAAU,CAiNjE;AAUD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,GAAG,MAAM,CAQrE"}
|
|
@@ -100,13 +100,16 @@ export function createDispatcher(deps) {
|
|
|
100
100
|
children: skip.childCount,
|
|
101
101
|
});
|
|
102
102
|
}
|
|
103
|
-
const
|
|
103
|
+
const active = state.issues
|
|
104
|
+
.filter((issue) => issue.status === "in-progress")
|
|
105
|
+
.toSorted((a, b) => a.id.localeCompare(b.id));
|
|
106
|
+
const activeCount = active.length;
|
|
104
107
|
const slots = config.orchestrator.maximumInProgress - activeCount;
|
|
105
108
|
// Narrow Todo to tickets that opted in via an `agent-*` label.
|
|
106
109
|
// Unlabeled tickets are not groundcrew's concern even when in Todo.
|
|
107
110
|
const todo = state.issues.filter((issue) => issue.status === "todo" && isGroundcrewIssue(issue));
|
|
108
111
|
if (slots <= 0) {
|
|
109
|
-
log(`At capacity (${activeCount}/${config.orchestrator.maximumInProgress}), no new work to start${idleSuffix}`);
|
|
112
|
+
log(`At capacity (${activeCount}/${config.orchestrator.maximumInProgress})${formatActiveSlotList(active)}, no new work to start${idleSuffix}`);
|
|
110
113
|
return;
|
|
111
114
|
}
|
|
112
115
|
if (todo.length === 0) {
|
|
@@ -177,7 +180,7 @@ export function createDispatcher(deps) {
|
|
|
177
180
|
return;
|
|
178
181
|
}
|
|
179
182
|
const dispatchable = starts;
|
|
180
|
-
log(
|
|
183
|
+
log(`Slots ${activeCount}/${config.orchestrator.maximumInProgress} used${formatActiveSlotList(active)}, starting ${dispatchable.length} ticket(s): ${dispatchable.map(({ issue }) => `${naturalIdFromCanonical(issue.id)}(${issue.model})`).join(", ")}`);
|
|
181
184
|
logEvent("dispatch", {
|
|
182
185
|
outcome: "starting",
|
|
183
186
|
tickets: dispatchable.map(({ issue }) => `${naturalIdFromCanonical(issue.id)}:${issue.model}`),
|
|
@@ -196,3 +199,12 @@ function formatUsageExhaustion(exhaustion) {
|
|
|
196
199
|
}
|
|
197
200
|
return `${exhaustion.model} weekly at ${exhaustion.usedPercentage.toFixed(1)}% (> ${exhaustion.allowedPercentage.toFixed(1)}% paced budget), resets in ${exhaustion.resetMinutes}m — skipping its tickets`;
|
|
198
201
|
}
|
|
202
|
+
export function formatActiveSlotList(active) {
|
|
203
|
+
if (active.length === 0) {
|
|
204
|
+
return "";
|
|
205
|
+
}
|
|
206
|
+
const entries = active
|
|
207
|
+
.map((issue) => `${naturalIdFromCanonical(issue.id)}(${issue.model ?? "?"})`)
|
|
208
|
+
.join(", ");
|
|
209
|
+
return ` [${entries}]`;
|
|
210
|
+
}
|
|
@@ -37,11 +37,11 @@ export interface Issue {
|
|
|
37
37
|
/**
|
|
38
38
|
* `undefined` unless the ticket is in Todo with a parseable `agent-*` label
|
|
39
39
|
* and a known-repo reference in its description — i.e. the dispatcher would
|
|
40
|
-
* actually pick it up.
|
|
41
|
-
* tick-spam warnings on already-finished work.
|
|
40
|
+
* actually pick it up. Non-Todo tickets do not resolve repositories because
|
|
41
|
+
* that would invite tick-spam warnings on already-finished work.
|
|
42
42
|
*/
|
|
43
43
|
repository: string | undefined;
|
|
44
|
-
/**
|
|
44
|
+
/** Parsed from the `agent-*` label when present, including non-Todo tickets for slot logs. */
|
|
45
45
|
model: string | undefined;
|
|
46
46
|
teamId: string;
|
|
47
47
|
blockers: Blocker[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/linear/fetch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGtD,OAAO,EAIL,KAAK,eAAe,EACrB,MAAM,cAAc,CAAC;AAEtB,eAAO,MAAM,gBAAgB,MAAM,CAAC;AAYpC,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B;;;;OAIG;IACH,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;CAC/B;AAED,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,uFAAuF;IACvF,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,
|
|
1
|
+
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/linear/fetch.ts"],"names":[],"mappings":"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"}
|
|
@@ -142,17 +142,21 @@ export function modelForResolution(resolution) {
|
|
|
142
142
|
}
|
|
143
143
|
return "any";
|
|
144
144
|
}
|
|
145
|
-
function
|
|
145
|
+
function resolveAgentMetadata(arguments_) {
|
|
146
146
|
const { ticket, description, modelResolution, config, isTodo } = arguments_;
|
|
147
147
|
let repository;
|
|
148
148
|
let model;
|
|
149
|
-
if (modelResolution.kind
|
|
149
|
+
if (modelResolution.kind === "no-label") {
|
|
150
|
+
return { repository, model };
|
|
151
|
+
}
|
|
152
|
+
model = modelForResolution(modelResolution);
|
|
153
|
+
if (isTodo) {
|
|
150
154
|
const resolution = resolveRepositoryFor({ description, config });
|
|
151
155
|
if (resolution.kind === "ok") {
|
|
152
156
|
({ repository } = resolution);
|
|
153
|
-
model = modelForResolution(modelResolution);
|
|
154
157
|
}
|
|
155
158
|
else {
|
|
159
|
+
model = undefined;
|
|
156
160
|
log(`WARNING: ${ticket} has an ${AGENT_LABEL_PREFIX}* label but no known repository in its description; skipping dispatch. Add one of workspace.knownRepositories to the description, or remove the ${AGENT_LABEL_PREFIX}* label: ${config.workspace.knownRepositories.join(", ")}`);
|
|
157
161
|
}
|
|
158
162
|
}
|
|
@@ -180,7 +184,7 @@ function buildLinearIssue(input) {
|
|
|
180
184
|
function issueFromNode(node, config) {
|
|
181
185
|
const modelResolution = resolveModelFor({ labels: node.labels.nodes, config });
|
|
182
186
|
warnIfDisabledFallback(node.identifier, modelResolution, config);
|
|
183
|
-
const { repository, model } =
|
|
187
|
+
const { repository, model } = resolveAgentMetadata({
|
|
184
188
|
ticket: node.identifier,
|
|
185
189
|
/* v8 ignore next @preserve -- BoardIssues query selects description; the ?? guard normalises a null vs undefined edge */
|
|
186
190
|
description: node.description ?? undefined,
|
|
@@ -59,9 +59,9 @@ export interface Issue {
|
|
|
59
59
|
title: string;
|
|
60
60
|
description: string;
|
|
61
61
|
status: CanonicalStatus;
|
|
62
|
-
/** `undefined` when the ticket
|
|
62
|
+
/** `undefined` when the ticket is not dispatchable to a repository. */
|
|
63
63
|
repository: string | undefined;
|
|
64
|
-
/**
|
|
64
|
+
/** Parsed agent model when the source can resolve one; may be present on non-Todo tickets for logs. */
|
|
65
65
|
model: string | undefined;
|
|
66
66
|
assignee: string;
|
|
67
67
|
updatedAt: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ticketSource.d.ts","sourceRoot":"","sources":["../../src/lib/ticketSource.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,aAAa,GAAG,WAAW,GAAG,MAAM,GAAG,OAAO,CAAC;AAEtF,MAAM,WAAW,OAAO;IACtB,6DAA6D;IAC7D,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,eAAe,CAAC;IACxB;;;;;;;;;;;;;OAaG;IACH,YAAY,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;IACtC;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,KAAK;IACpB,kFAAkF;IAClF,EAAE,EAAE,MAAM,CAAC;IACX,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,eAAe,CAAC;IACxB,
|
|
1
|
+
{"version":3,"file":"ticketSource.d.ts","sourceRoot":"","sources":["../../src/lib/ticketSource.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED