@north-light/crouter 0.3.192 → 0.3.194
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/client.d.ts +31 -10
- package/dist/api/client.js +83 -24
- package/dist/api/dto/bash-jobs.d.ts +24 -0
- package/dist/api/dto/bash-jobs.js +9 -0
- package/dist/api/dto/human.d.ts +3 -4
- package/dist/api/dto/inbox.d.ts +106 -65
- package/dist/api/dto/inbox.js +2 -8
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.js +1 -0
- package/dist/api/routes.d.ts +7 -0
- package/dist/api/routes.js +7 -0
- package/dist/builtin-memory/02-lifecycle/01-resident.md +1 -1
- package/dist/builtin-memory/internal/examples/imessage-assistant.md +1 -1
- package/dist/builtin-memory/internal/nodes-and-canvas.md +2 -2
- package/dist/builtin-memory/internal/storage-tiers.md +1 -1
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/serial/provider-rotation.test.ts +101 -3
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +6 -2
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +68 -14
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +87 -13
- package/dist/clients/attach/__tests__/chat-view-snapshot-ordering.test.js +2 -2
- package/dist/clients/attach/__tests__/group-activity.test.js +2 -2
- package/dist/clients/attach/chrome/canvas-panels.d.ts +1 -1
- package/dist/clients/attach/chrome/canvas-panels.js +1 -1
- package/dist/clients/attach/input/overlay-owner.js +1 -1
- package/dist/clients/attach/overlays/auth.js +34 -8
- package/dist/clients/attach/overlays/pickers.d.ts +5 -8
- package/dist/clients/attach/overlays/pickers.js +37 -43
- package/dist/clients/attach/viewer.js +643 -620
- package/dist/clients/inbox/__tests__/serial/inbox-controller.test.js +38 -128
- package/dist/clients/inbox/__tests__/serial/mount-panel.test.js +72 -148
- package/dist/clients/inbox/controller.d.ts +2 -3
- package/dist/clients/inbox/controller.js +41 -42
- package/dist/clients/inbox/page-adapter.d.ts +33 -0
- package/dist/clients/inbox/page-adapter.js +54 -0
- package/dist/clients/inbox/resolve.d.ts +2 -2
- package/dist/clients/inbox/resolve.js +1 -1
- package/dist/clients/inbox/review-visibility.d.ts +1 -1
- package/dist/clients/inbox/review-visibility.js +1 -1
- package/dist/clients/inbox/tui/ansi.d.ts +1 -1
- package/dist/clients/inbox/tui/ansi.js +2 -2
- package/dist/clients/inbox/tui/input.d.ts +1 -3
- package/dist/clients/inbox/tui/input.js +242 -553
- package/dist/clients/inbox/tui/panel.d.ts +3 -1
- package/dist/clients/inbox/tui/panel.js +59 -187
- package/dist/clients/inbox/tui/render.d.ts +0 -25
- package/dist/clients/inbox/tui/render.js +165 -416
- package/dist/clients/inbox/tui/slots.d.ts +32 -0
- package/dist/clients/inbox/tui/slots.js +156 -0
- package/dist/clients/inbox/tui/types.d.ts +25 -13
- package/dist/clients/inbox/tui.js +5 -3
- package/dist/commands/attention.js +2 -2
- package/dist/commands/human/doc.js +66 -20
- package/dist/commands/human/prompts.d.ts +3 -3
- package/dist/commands/human/prompts.js +158 -112
- package/dist/commands/human/queue.d.ts +0 -1
- package/dist/commands/human/queue.js +34 -94
- package/dist/commands/human/shared.d.ts +10 -4
- package/dist/commands/human/shared.js +62 -13
- package/dist/commands/human.js +8 -4
- package/dist/commands/memory/read.js +13 -5
- package/dist/commands/node/bash.js +18 -30
- package/dist/commands/node/lifecycle.js +2 -2
- package/dist/commands/surface/node/focus.js +1 -1
- package/dist/core/__tests__/human-deliver.test.js +40 -46
- package/dist/core/__tests__/seam/broker-attach-stream.test.js +7 -1
- package/dist/core/__tests__/seam/dormancy-release.test.js +64 -10
- package/dist/core/__tests__/serial/human-deliver-e2e.test.js +40 -31
- package/dist/core/__tests__/serial/spawn-root.test.js +3 -1
- package/dist/core/__tests__/spawn-worktree-id-conflict.test.js +3 -1
- package/dist/core/auth-interaction.d.ts +2 -2
- package/dist/core/bash-jobs.d.ts +43 -0
- package/dist/core/bash-jobs.js +96 -2
- package/dist/core/canvas/__tests__/attention.test.js +16 -10
- package/dist/core/canvas/__tests__/render-remote.test.js +9 -3
- package/dist/core/canvas/attention.js +1 -1
- package/dist/core/canvas/browse/app.js +1 -1
- package/dist/core/canvas/nav-model.d.ts +1 -1
- package/dist/core/canvas/nav-model.js +1 -1
- package/dist/core/canvas/remote-canvas-source.js +1 -1
- package/dist/core/canvas/types.d.ts +2 -1
- package/dist/core/config.js +4 -1
- package/dist/core/human/__tests__/page-render.test.d.ts +1 -0
- package/dist/core/human/__tests__/page-render.test.js +49 -0
- package/dist/core/human/__tests__/page-tickets.test.d.ts +1 -0
- package/dist/core/human/__tests__/page-tickets.test.js +112 -0
- package/dist/core/human/__tests__/page.test.d.ts +1 -0
- package/dist/core/human/__tests__/page.test.js +139 -0
- package/dist/core/human/__tests__/serial/inbox-core.test.js +42 -32
- package/dist/core/human/claim.js +2 -2
- package/dist/core/human/convention.d.ts +4 -4
- package/dist/core/human/convention.js +6 -13
- package/dist/core/human/markdown-html.d.ts +8 -0
- package/dist/core/human/markdown-html.js +581 -0
- package/dist/core/human/page-catalog.d.ts +6 -0
- package/dist/core/human/page-catalog.js +43 -0
- package/dist/core/human/page-render.d.ts +3 -0
- package/dist/core/human/page-render.js +131 -0
- package/dist/core/human/page-schema.d.ts +312 -0
- package/dist/core/human/page-schema.js +291 -0
- package/dist/core/human/page-synth.d.ts +9 -0
- package/dist/core/human/page-synth.js +17 -0
- package/dist/core/human/page.d.ts +22 -0
- package/dist/core/human/page.js +427 -0
- package/dist/core/human/review-schema.d.ts +19 -0
- package/dist/core/human/review-schema.js +34 -0
- package/dist/core/human/scan.d.ts +12 -3
- package/dist/core/human/scan.js +69 -26
- package/dist/core/human/summary.d.ts +5 -6
- package/dist/core/human/summary.js +54 -37
- package/dist/core/human/tickets.d.ts +61 -11
- package/dist/core/human/tickets.js +100 -57
- package/dist/core/human/types.d.ts +21 -66
- package/dist/core/human/types.js +1 -5
- package/dist/core/inspector/model.d.ts +5 -0
- package/dist/core/inspector/model.js +5 -0
- package/dist/core/inspector/text.js +2 -2
- package/dist/core/inspector/tui.js +10 -3
- package/dist/core/keybindings/catalog.d.ts +1 -1
- package/dist/core/keybindings/catalog.js +4 -2
- package/dist/core/preview-registry.js +0 -1
- package/dist/core/review/ticket-filter.d.ts +1 -1
- package/dist/core/review/ticket-filter.js +2 -8
- package/dist/core/runtime/broker/read-ops.js +3 -0
- package/dist/core/runtime/broker.js +19 -10
- package/dist/core/runtime/package-health.js +1 -1
- package/dist/core/runtime/persona.js +2 -1
- package/dist/core/runtime/tmux-bindings.js +8 -1
- package/dist/core/termrender/termrender.d.ts +1 -1
- package/dist/core/termrender/termrender.js +2 -2
- package/dist/core/termrender/version.d.ts +1 -1
- package/dist/core/termrender/version.js +1 -1
- package/dist/core/tui/page-host.d.ts +1 -1
- package/dist/core/tui/page-host.js +2 -2
- package/dist/core/user-settings.d.ts +19 -0
- package/dist/core/user-settings.js +22 -0
- package/dist/daemon/api/handlers/bash-jobs.d.ts +2 -0
- package/dist/daemon/api/handlers/bash-jobs.js +90 -0
- package/dist/daemon/api/handlers/human.js +16 -14
- package/dist/daemon/api/handlers/inbox.js +311 -227
- package/dist/daemon/api/router.d.ts +5 -1
- package/dist/daemon/api/router.js +5 -0
- package/dist/daemon/api/server.js +2 -0
- package/dist/daemon/cron-run.js +23 -10
- package/dist/daemon/human/finish.d.ts +8 -3
- package/dist/daemon/human/finish.js +35 -15
- package/dist/daemon/reconcilers/broker-supervision.js +7 -1
- package/dist/daemon/reconcilers/dormant-inbox.js +8 -0
- package/dist/daemon/reconcilers/live-obligation.d.ts +2 -0
- package/dist/daemon/reconcilers/live-obligation.js +11 -0
- package/dist/pages/bundle.css +1 -0
- package/dist/pages/bundle.js +1347 -0
- package/dist/pages/comments.d.ts +34 -0
- package/dist/pages/comments.js +72 -0
- package/dist/pages/elements/cards.d.ts +17 -0
- package/dist/pages/elements/cards.js +785 -0
- package/dist/pages/elements/chart.d.ts +1 -0
- package/dist/pages/elements/chart.js +648 -0
- package/dist/pages/elements/options.d.ts +21 -0
- package/dist/pages/elements/options.js +604 -0
- package/dist/pages/elements/pages.d.ts +24 -0
- package/dist/pages/elements/pages.js +355 -0
- package/dist/pages/elements/slot.d.ts +21 -0
- package/dist/pages/elements/slot.js +105 -0
- package/dist/pages/elements/table.d.ts +19 -0
- package/dist/pages/elements/table.js +906 -0
- package/dist/pages/elements/text.d.ts +25 -0
- package/dist/pages/elements/text.js +951 -0
- package/dist/pages/entry.d.ts +8 -0
- package/dist/pages/entry.js +8 -0
- package/dist/pages/host.d.ts +132 -0
- package/dist/pages/host.js +149 -0
- package/dist/pages/register.d.ts +2 -0
- package/dist/pages/register.js +3 -0
- package/dist/pages/slot-config.d.ts +36 -0
- package/dist/pages/slot-config.js +50 -0
- package/dist/pages/types.d.ts +98 -0
- package/dist/pages/types.js +23 -0
- package/dist/pi-extensions/canvas-bash-valve.d.ts +4 -2
- package/dist/pi-extensions/canvas-bash-valve.js +25 -7
- package/dist/types.d.ts +4 -0
- package/dist/types.js +2 -0
- package/package.json +8 -8
- package/runtime.lock.json +156 -101
- package/scripts/install-runtime.mjs +172 -5
- package/dist/clients/inbox/deck-adapter.d.ts +0 -29
- package/dist/clients/inbox/deck-adapter.js +0 -63
- package/dist/core/human/deck-factories.d.ts +0 -8
- package/dist/core/human/deck-factories.js +0 -15
- package/dist/core/human/deck-schema.d.ts +0 -70
- package/dist/core/human/deck-schema.js +0 -92
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `window.crtr` — the one door out of a page.
|
|
3
|
+
*
|
|
4
|
+
* An element renders inside a host (Northlight's srcdoc host today, a crtrd-served
|
|
5
|
+
* page later) that installs this bridge before the bundle loads. Everything an element
|
|
6
|
+
* needs from the outside world arrives through it: there is no `fetch`, no `XMLHttpRequest`,
|
|
7
|
+
* no direct network access anywhere under `src/pages/`. An element that cannot get what it
|
|
8
|
+
* needs renders a named unavailable state; it never falls back to reaching out itself.
|
|
9
|
+
*
|
|
10
|
+
* Two things the bridge deliberately does NOT have:
|
|
11
|
+
*
|
|
12
|
+
* - **No `save` and no `dismiss`.** Both are host chrome — a frame around the page, not
|
|
13
|
+
* markup inside it — so they are the host's own UI actions and are never advertised to
|
|
14
|
+
* page code.
|
|
15
|
+
* - **No per-element resolution.** `respond()` is a local-state write plus a request that
|
|
16
|
+
* the host autosave the partial map; it does not resolve the ticket. Only the pager's
|
|
17
|
+
* submit affordance calls `submit()`, which posts the complete map once.
|
|
18
|
+
*
|
|
19
|
+
* The host is optional at the type level (`window.crtr?`) because a page can be opened
|
|
20
|
+
* bare — dropped in a browser, or rendered by a host that installs nothing. Elements read
|
|
21
|
+
* the bridge through the accessors below rather than touching `window.crtr` directly, so
|
|
22
|
+
* that absence is typed and total instead of an `as any` at each call site.
|
|
23
|
+
*/
|
|
24
|
+
import type { SlotResponse } from './types.js';
|
|
25
|
+
/** Live host theme tokens, as `--crtr-*` custom-property names mapped to values. */
|
|
26
|
+
export interface CrtrThemeBridge {
|
|
27
|
+
current(): Record<string, string>;
|
|
28
|
+
/** Registers `listener` for later theme changes; returns its unsubscribe. */
|
|
29
|
+
subscribe(listener: (tokens: Record<string, string>) => void): () => void;
|
|
30
|
+
}
|
|
31
|
+
/** Data behind a `source`-bearing config (table, cards, chart). */
|
|
32
|
+
export interface CrtrArtifactBridge {
|
|
33
|
+
/** Resolves the already-parsed data for `source`, or rejects when it is unreachable. */
|
|
34
|
+
data(source: string): Promise<unknown>;
|
|
35
|
+
}
|
|
36
|
+
/** What `mountWorkspaceComponent` can answer: the host rendered it, or it has no renderer. */
|
|
37
|
+
export type WorkspaceMountOutcome = 'mounted' | 'unavailable';
|
|
38
|
+
/** The bridge a host installs at `window.crtr`. */
|
|
39
|
+
export interface CrtrHost {
|
|
40
|
+
/**
|
|
41
|
+
* Records this slot's complete current response and asks the host to autosave the
|
|
42
|
+
* partial map. Called on every user change. NOT ticket resolution.
|
|
43
|
+
*/
|
|
44
|
+
respond(slotId: string, response: SlotResponse): void;
|
|
45
|
+
/** Posts the complete response map once. Only the pager's submit affordance calls it. */
|
|
46
|
+
submit(): Promise<void>;
|
|
47
|
+
/** Flushes the pending autosave of the partial map. */
|
|
48
|
+
progress(): Promise<void>;
|
|
49
|
+
readonly theme: CrtrThemeBridge;
|
|
50
|
+
readonly artifact: CrtrArtifactBridge;
|
|
51
|
+
/**
|
|
52
|
+
* Asks the host to render a product-registered (`unvalidated`) slot into `element`.
|
|
53
|
+
* A host with no renderer for `kind` answers `'unavailable'`.
|
|
54
|
+
*/
|
|
55
|
+
mountWorkspaceComponent(element: HTMLElement, kind: string, config: Record<string, unknown>): Promise<WorkspaceMountOutcome>;
|
|
56
|
+
}
|
|
57
|
+
declare global {
|
|
58
|
+
interface Window {
|
|
59
|
+
/**
|
|
60
|
+
* Installed by the host before the bundle loads. Optional: a page opened bare has
|
|
61
|
+
* no bridge, and every element must still render.
|
|
62
|
+
*/
|
|
63
|
+
crtr?: CrtrHost;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* The outcome of a bridge call. `unavailable` means the door is not there — no host, or a
|
|
68
|
+
* host that does not implement this method. `failed` means the host was asked and said no,
|
|
69
|
+
* and `reason` is what it said. Elements distinguish them because "this page is not hosted"
|
|
70
|
+
* and "the server rejected your answer" are different things to show a person.
|
|
71
|
+
*/
|
|
72
|
+
export type HostCall = {
|
|
73
|
+
status: 'ok';
|
|
74
|
+
} | {
|
|
75
|
+
status: 'unavailable';
|
|
76
|
+
reason: string;
|
|
77
|
+
} | {
|
|
78
|
+
status: 'failed';
|
|
79
|
+
reason: string;
|
|
80
|
+
};
|
|
81
|
+
/** The outcome of an artifact read, with the same three-way split as `HostCall`. */
|
|
82
|
+
export type ArtifactData = {
|
|
83
|
+
status: 'ok';
|
|
84
|
+
data: unknown;
|
|
85
|
+
} | {
|
|
86
|
+
status: 'unavailable';
|
|
87
|
+
reason: string;
|
|
88
|
+
} | {
|
|
89
|
+
status: 'failed';
|
|
90
|
+
reason: string;
|
|
91
|
+
};
|
|
92
|
+
/** The installed bridge, or `undefined` on a bare page. */
|
|
93
|
+
export declare function host(): CrtrHost | undefined;
|
|
94
|
+
/**
|
|
95
|
+
* Writes this slot's complete current response to the host's in-frame map and requests an
|
|
96
|
+
* autosave. Elements call this on every user change with the whole response object, never a
|
|
97
|
+
* delta. Safe on a bare page: the element's own local state is authoritative for rendering,
|
|
98
|
+
* so an unavailable host only means the answer is not being persisted.
|
|
99
|
+
*/
|
|
100
|
+
export declare function respond(slotId: string, response: SlotResponse): HostCall;
|
|
101
|
+
/**
|
|
102
|
+
* Posts the complete response map once, resolving the ticket. Only the pager's submit
|
|
103
|
+
* affordance calls this.
|
|
104
|
+
*/
|
|
105
|
+
export declare function submit(): Promise<HostCall>;
|
|
106
|
+
/** Flushes the host's pending autosave of the partial map. Never resolves the ticket. */
|
|
107
|
+
export declare function progress(): Promise<HostCall>;
|
|
108
|
+
/**
|
|
109
|
+
* The host's current theme token values. Empty on a bare page — which is correct and needs
|
|
110
|
+
* no handling, because `bundle.css` declares every `--crtr-*` token at zero specificity and
|
|
111
|
+
* elements style through those custom properties rather than through this map. Read it only
|
|
112
|
+
* when a value must reach somewhere CSS cannot, such as an SVG attribute.
|
|
113
|
+
*/
|
|
114
|
+
export declare function themeTokens(): Record<string, string>;
|
|
115
|
+
/**
|
|
116
|
+
* Subscribes to later theme changes. Always returns an unsubscribe, so a caller can wire it
|
|
117
|
+
* to `disconnectedCallback` without checking whether a host was there.
|
|
118
|
+
*/
|
|
119
|
+
export declare function subscribeTheme(listener: (tokens: Record<string, string>) => void): () => void;
|
|
120
|
+
/**
|
|
121
|
+
* Reads the data behind a `source`-bearing config. The host resolves the reference and hands
|
|
122
|
+
* back parsed data; an element never resolves a reference itself and never fetches a URL.
|
|
123
|
+
* Anything other than `'ok'` is a named unavailable state to render, not a reason to retry
|
|
124
|
+
* some other way.
|
|
125
|
+
*/
|
|
126
|
+
export declare function artifactData(source: string): Promise<ArtifactData>;
|
|
127
|
+
/**
|
|
128
|
+
* Asks the host to render a product-registered slot into `element`. A bare page, a host with
|
|
129
|
+
* no registry, and a host whose mount threw all answer `'unavailable'` — the escape element's
|
|
130
|
+
* named unavailable state is the only other outcome.
|
|
131
|
+
*/
|
|
132
|
+
export declare function mountWorkspaceComponent(element: HTMLElement, kind: string, config: Record<string, unknown>): Promise<WorkspaceMountOutcome>;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `window.crtr` — the one door out of a page.
|
|
3
|
+
*
|
|
4
|
+
* An element renders inside a host (Northlight's srcdoc host today, a crtrd-served
|
|
5
|
+
* page later) that installs this bridge before the bundle loads. Everything an element
|
|
6
|
+
* needs from the outside world arrives through it: there is no `fetch`, no `XMLHttpRequest`,
|
|
7
|
+
* no direct network access anywhere under `src/pages/`. An element that cannot get what it
|
|
8
|
+
* needs renders a named unavailable state; it never falls back to reaching out itself.
|
|
9
|
+
*
|
|
10
|
+
* Two things the bridge deliberately does NOT have:
|
|
11
|
+
*
|
|
12
|
+
* - **No `save` and no `dismiss`.** Both are host chrome — a frame around the page, not
|
|
13
|
+
* markup inside it — so they are the host's own UI actions and are never advertised to
|
|
14
|
+
* page code.
|
|
15
|
+
* - **No per-element resolution.** `respond()` is a local-state write plus a request that
|
|
16
|
+
* the host autosave the partial map; it does not resolve the ticket. Only the pager's
|
|
17
|
+
* submit affordance calls `submit()`, which posts the complete map once.
|
|
18
|
+
*
|
|
19
|
+
* The host is optional at the type level (`window.crtr?`) because a page can be opened
|
|
20
|
+
* bare — dropped in a browser, or rendered by a host that installs nothing. Elements read
|
|
21
|
+
* the bridge through the accessors below rather than touching `window.crtr` directly, so
|
|
22
|
+
* that absence is typed and total instead of an `as any` at each call site.
|
|
23
|
+
*/
|
|
24
|
+
/** The installed bridge, or `undefined` on a bare page. */
|
|
25
|
+
export function host() {
|
|
26
|
+
return typeof window === 'undefined' ? undefined : window.crtr;
|
|
27
|
+
}
|
|
28
|
+
function reasonOf(error) {
|
|
29
|
+
if (error instanceof Error && error.message !== '')
|
|
30
|
+
return error.message;
|
|
31
|
+
const text = String(error);
|
|
32
|
+
return text === '' ? 'unknown error' : text;
|
|
33
|
+
}
|
|
34
|
+
function missing(method) {
|
|
35
|
+
return { status: 'unavailable', reason: `host bridge does not provide ${method}()` };
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Writes this slot's complete current response to the host's in-frame map and requests an
|
|
39
|
+
* autosave. Elements call this on every user change with the whole response object, never a
|
|
40
|
+
* delta. Safe on a bare page: the element's own local state is authoritative for rendering,
|
|
41
|
+
* so an unavailable host only means the answer is not being persisted.
|
|
42
|
+
*/
|
|
43
|
+
export function respond(slotId, response) {
|
|
44
|
+
const bridge = host();
|
|
45
|
+
if (typeof bridge?.respond !== 'function')
|
|
46
|
+
return missing('respond');
|
|
47
|
+
try {
|
|
48
|
+
bridge.respond(slotId, response);
|
|
49
|
+
return { status: 'ok' };
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
return { status: 'failed', reason: reasonOf(error) };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Posts the complete response map once, resolving the ticket. Only the pager's submit
|
|
57
|
+
* affordance calls this.
|
|
58
|
+
*/
|
|
59
|
+
export async function submit() {
|
|
60
|
+
const bridge = host();
|
|
61
|
+
if (typeof bridge?.submit !== 'function')
|
|
62
|
+
return missing('submit');
|
|
63
|
+
try {
|
|
64
|
+
await bridge.submit();
|
|
65
|
+
return { status: 'ok' };
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
return { status: 'failed', reason: reasonOf(error) };
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/** Flushes the host's pending autosave of the partial map. Never resolves the ticket. */
|
|
72
|
+
export async function progress() {
|
|
73
|
+
const bridge = host();
|
|
74
|
+
if (typeof bridge?.progress !== 'function')
|
|
75
|
+
return missing('progress');
|
|
76
|
+
try {
|
|
77
|
+
await bridge.progress();
|
|
78
|
+
return { status: 'ok' };
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
return { status: 'failed', reason: reasonOf(error) };
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* The host's current theme token values. Empty on a bare page — which is correct and needs
|
|
86
|
+
* no handling, because `bundle.css` declares every `--crtr-*` token at zero specificity and
|
|
87
|
+
* elements style through those custom properties rather than through this map. Read it only
|
|
88
|
+
* when a value must reach somewhere CSS cannot, such as an SVG attribute.
|
|
89
|
+
*/
|
|
90
|
+
export function themeTokens() {
|
|
91
|
+
const bridge = host();
|
|
92
|
+
if (typeof bridge?.theme?.current !== 'function')
|
|
93
|
+
return {};
|
|
94
|
+
try {
|
|
95
|
+
return bridge.theme.current();
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return {};
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Subscribes to later theme changes. Always returns an unsubscribe, so a caller can wire it
|
|
103
|
+
* to `disconnectedCallback` without checking whether a host was there.
|
|
104
|
+
*/
|
|
105
|
+
export function subscribeTheme(listener) {
|
|
106
|
+
const bridge = host();
|
|
107
|
+
if (typeof bridge?.theme?.subscribe !== 'function')
|
|
108
|
+
return () => { };
|
|
109
|
+
try {
|
|
110
|
+
const unsubscribe = bridge.theme.subscribe(listener);
|
|
111
|
+
return typeof unsubscribe === 'function' ? unsubscribe : () => { };
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return () => { };
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Reads the data behind a `source`-bearing config. The host resolves the reference and hands
|
|
119
|
+
* back parsed data; an element never resolves a reference itself and never fetches a URL.
|
|
120
|
+
* Anything other than `'ok'` is a named unavailable state to render, not a reason to retry
|
|
121
|
+
* some other way.
|
|
122
|
+
*/
|
|
123
|
+
export async function artifactData(source) {
|
|
124
|
+
const bridge = host();
|
|
125
|
+
if (typeof bridge?.artifact?.data !== 'function')
|
|
126
|
+
return missing('artifact.data');
|
|
127
|
+
try {
|
|
128
|
+
return { status: 'ok', data: await bridge.artifact.data(source) };
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
return { status: 'failed', reason: reasonOf(error) };
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Asks the host to render a product-registered slot into `element`. A bare page, a host with
|
|
136
|
+
* no registry, and a host whose mount threw all answer `'unavailable'` — the escape element's
|
|
137
|
+
* named unavailable state is the only other outcome.
|
|
138
|
+
*/
|
|
139
|
+
export async function mountWorkspaceComponent(element, kind, config) {
|
|
140
|
+
const bridge = host();
|
|
141
|
+
if (typeof bridge?.mountWorkspaceComponent !== 'function')
|
|
142
|
+
return 'unavailable';
|
|
143
|
+
try {
|
|
144
|
+
return await bridge.mountWorkspaceComponent(element, kind, config);
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
return 'unavailable';
|
|
148
|
+
}
|
|
149
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reading a slot's config out of the DOM.
|
|
3
|
+
*
|
|
4
|
+
* The host renders each slot as
|
|
5
|
+
* `<crtr-KIND slot-id="ID"><script type="application/json">CONFIG_JSON</script></crtr-KIND>`,
|
|
6
|
+
* and every element does the same three things in `connectedCallback`: find that script child,
|
|
7
|
+
* parse it, and render a named error state instead of throwing when it is missing or malformed.
|
|
8
|
+
* That is one behaviour, so it lives here once.
|
|
9
|
+
*
|
|
10
|
+
* **What is and is not checked.** The JSON's *shape* was already validated by
|
|
11
|
+
* `validatePageManifest` before the manifest was stored, and the renderer emits from that
|
|
12
|
+
* validated manifest — so an element may trust the parsed object against its own config type.
|
|
13
|
+
* What is not guaranteed is that the script child is there at all and that its text parses: a
|
|
14
|
+
* page can be hand-written, truncated, or rendered by something else. Those two failures are
|
|
15
|
+
* what this module reports.
|
|
16
|
+
*/
|
|
17
|
+
/** A parsed config, or the reason the element should render an error state instead. */
|
|
18
|
+
export type SlotConfigResult<T> = {
|
|
19
|
+
status: 'ok';
|
|
20
|
+
config: T;
|
|
21
|
+
} | {
|
|
22
|
+
status: 'invalid';
|
|
23
|
+
reason: string;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Reads and parses the JSON script child of `element`.
|
|
27
|
+
*
|
|
28
|
+
* `T` is the element's own mirrored config type and is asserted, not verified — see the note
|
|
29
|
+
* above on why that is sound. Never throws.
|
|
30
|
+
*/
|
|
31
|
+
export declare function readSlotConfig<T = Record<string, unknown>>(element: HTMLElement): SlotConfigResult<T>;
|
|
32
|
+
/**
|
|
33
|
+
* The slot id the host addressed this element by — the key `respond()` takes. Absent on a
|
|
34
|
+
* display-only slot, which has no id and produces no response.
|
|
35
|
+
*/
|
|
36
|
+
export declare function readSlotId(element: HTMLElement): string | undefined;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reading a slot's config out of the DOM.
|
|
3
|
+
*
|
|
4
|
+
* The host renders each slot as
|
|
5
|
+
* `<crtr-KIND slot-id="ID"><script type="application/json">CONFIG_JSON</script></crtr-KIND>`,
|
|
6
|
+
* and every element does the same three things in `connectedCallback`: find that script child,
|
|
7
|
+
* parse it, and render a named error state instead of throwing when it is missing or malformed.
|
|
8
|
+
* That is one behaviour, so it lives here once.
|
|
9
|
+
*
|
|
10
|
+
* **What is and is not checked.** The JSON's *shape* was already validated by
|
|
11
|
+
* `validatePageManifest` before the manifest was stored, and the renderer emits from that
|
|
12
|
+
* validated manifest — so an element may trust the parsed object against its own config type.
|
|
13
|
+
* What is not guaranteed is that the script child is there at all and that its text parses: a
|
|
14
|
+
* page can be hand-written, truncated, or rendered by something else. Those two failures are
|
|
15
|
+
* what this module reports.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Reads and parses the JSON script child of `element`.
|
|
19
|
+
*
|
|
20
|
+
* `T` is the element's own mirrored config type and is asserted, not verified — see the note
|
|
21
|
+
* above on why that is sound. Never throws.
|
|
22
|
+
*/
|
|
23
|
+
export function readSlotConfig(element) {
|
|
24
|
+
const script = element.querySelector('script[type="application/json"]');
|
|
25
|
+
if (script === null)
|
|
26
|
+
return { status: 'invalid', reason: 'slot has no application/json config' };
|
|
27
|
+
const text = script.textContent ?? '';
|
|
28
|
+
if (text.trim() === '')
|
|
29
|
+
return { status: 'invalid', reason: 'slot config is empty' };
|
|
30
|
+
let parsed;
|
|
31
|
+
try {
|
|
32
|
+
parsed = JSON.parse(text);
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
const detail = error instanceof Error && error.message !== '' ? error.message : 'invalid JSON';
|
|
36
|
+
return { status: 'invalid', reason: `slot config is not valid JSON: ${detail}` };
|
|
37
|
+
}
|
|
38
|
+
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
|
|
39
|
+
return { status: 'invalid', reason: 'slot config must be a JSON object' };
|
|
40
|
+
}
|
|
41
|
+
return { status: 'ok', config: parsed };
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* The slot id the host addressed this element by — the key `respond()` takes. Absent on a
|
|
45
|
+
* display-only slot, which has no id and produces no response.
|
|
46
|
+
*/
|
|
47
|
+
export function readSlotId(element) {
|
|
48
|
+
const id = element.getAttribute('slot-id')?.trim();
|
|
49
|
+
return id === undefined || id === '' ? undefined : id;
|
|
50
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The response contract the page bundle produces, as plain browser-safe types.
|
|
3
|
+
*
|
|
4
|
+
* These mirror `src/core/human/page-schema.ts` field-for-field — `commentSchema`,
|
|
5
|
+
* `commentAnchorSchema`, and the four `*ResponseSchema`s — and are deliberately a
|
|
6
|
+
* separate declaration rather than an import: nothing under `src/pages/` may reach
|
|
7
|
+
* a runtime package (zod) or a module outside this directory, because the bundle is
|
|
8
|
+
* a browser IIFE. The schemas remain the source of truth; a change there is a change
|
|
9
|
+
* that must land here in the same commit.
|
|
10
|
+
*
|
|
11
|
+
* Two rules the shapes are built around:
|
|
12
|
+
*
|
|
13
|
+
* 1. **One comment shape everywhere.** Every response-bearing element carries
|
|
14
|
+
* comments, and every comment is `{ id, anchor, text }`. A comment on an option,
|
|
15
|
+
* a table row, a card, or a range of prose differs only in its `anchor`.
|
|
16
|
+
* 2. **Selection is ids, never indexes or values.** The agent authored the ids it is
|
|
17
|
+
* asking about, so the response keys straight off them.
|
|
18
|
+
*
|
|
19
|
+
* Config types are NOT here: a config is one element's private input, mirrored in that
|
|
20
|
+
* element's own module. A response is what crosses `window.crtr.respond`, so it is
|
|
21
|
+
* shared.
|
|
22
|
+
*/
|
|
23
|
+
/** What a comment is attached to. One union across every element. */
|
|
24
|
+
export type CommentAnchor =
|
|
25
|
+
/** The presented content as a whole. */
|
|
26
|
+
{
|
|
27
|
+
kind: 'whole';
|
|
28
|
+
}
|
|
29
|
+
/** One option of an `options` element. */
|
|
30
|
+
| {
|
|
31
|
+
kind: 'option';
|
|
32
|
+
optionId: string;
|
|
33
|
+
}
|
|
34
|
+
/** One row of a `table`. */
|
|
35
|
+
| {
|
|
36
|
+
kind: 'row';
|
|
37
|
+
rowId: string;
|
|
38
|
+
}
|
|
39
|
+
/** One column of a `table`. */
|
|
40
|
+
| {
|
|
41
|
+
kind: 'column';
|
|
42
|
+
columnId: string;
|
|
43
|
+
}
|
|
44
|
+
/** One card of a `cards` grid. */
|
|
45
|
+
| {
|
|
46
|
+
kind: 'card';
|
|
47
|
+
cardId: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* A character range of a `text` element's final text, review-style. `quote` is the
|
|
51
|
+
* text as it read when the comment was left, so the comment survives (readably) an
|
|
52
|
+
* edit that moves the offsets.
|
|
53
|
+
*/
|
|
54
|
+
| {
|
|
55
|
+
kind: 'range';
|
|
56
|
+
start: number;
|
|
57
|
+
end: number;
|
|
58
|
+
quote: string;
|
|
59
|
+
};
|
|
60
|
+
/** A user comment. The same shape in every element's response. */
|
|
61
|
+
export type Comment = {
|
|
62
|
+
/** Stable per comment; frame-local, minted by `newCommentId()`. */
|
|
63
|
+
id: string;
|
|
64
|
+
anchor: CommentAnchor;
|
|
65
|
+
text: string;
|
|
66
|
+
};
|
|
67
|
+
/** `options` — single or multi select, per-option comments, optional freetext. */
|
|
68
|
+
export type OptionsResponse = {
|
|
69
|
+
/** Always an array; a single-select answer is a one-element array. */
|
|
70
|
+
selectedOptionIds: string[];
|
|
71
|
+
comments: Comment[];
|
|
72
|
+
/** Present only when the config allows freetext and the user typed something. */
|
|
73
|
+
freetext?: string;
|
|
74
|
+
};
|
|
75
|
+
/** `text` — an edited draft and/or anchored comments on presented prose. */
|
|
76
|
+
export type TextResponse = {
|
|
77
|
+
/** The text as the user is leaving it. */
|
|
78
|
+
text: string;
|
|
79
|
+
/** True once `text` differs from what the agent presented. */
|
|
80
|
+
edited: boolean;
|
|
81
|
+
comments: Comment[];
|
|
82
|
+
};
|
|
83
|
+
/** `table` — row and/or column selection with anchored comments. */
|
|
84
|
+
export type TableResponse = {
|
|
85
|
+
selectedRowIds: string[];
|
|
86
|
+
selectedColumnIds: string[];
|
|
87
|
+
comments: Comment[];
|
|
88
|
+
};
|
|
89
|
+
/** `cards` — card selection with per-card comments. */
|
|
90
|
+
export type CardsResponse = {
|
|
91
|
+
selectedCardIds: string[];
|
|
92
|
+
comments: Comment[];
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Any slot response. The open member covers a product-registered `unvalidated` slot,
|
|
96
|
+
* whose shape only the product renderer knows.
|
|
97
|
+
*/
|
|
98
|
+
export type SlotResponse = OptionsResponse | TextResponse | TableResponse | CardsResponse | Record<string, unknown>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The response contract the page bundle produces, as plain browser-safe types.
|
|
3
|
+
*
|
|
4
|
+
* These mirror `src/core/human/page-schema.ts` field-for-field — `commentSchema`,
|
|
5
|
+
* `commentAnchorSchema`, and the four `*ResponseSchema`s — and are deliberately a
|
|
6
|
+
* separate declaration rather than an import: nothing under `src/pages/` may reach
|
|
7
|
+
* a runtime package (zod) or a module outside this directory, because the bundle is
|
|
8
|
+
* a browser IIFE. The schemas remain the source of truth; a change there is a change
|
|
9
|
+
* that must land here in the same commit.
|
|
10
|
+
*
|
|
11
|
+
* Two rules the shapes are built around:
|
|
12
|
+
*
|
|
13
|
+
* 1. **One comment shape everywhere.** Every response-bearing element carries
|
|
14
|
+
* comments, and every comment is `{ id, anchor, text }`. A comment on an option,
|
|
15
|
+
* a table row, a card, or a range of prose differs only in its `anchor`.
|
|
16
|
+
* 2. **Selection is ids, never indexes or values.** The agent authored the ids it is
|
|
17
|
+
* asking about, so the response keys straight off them.
|
|
18
|
+
*
|
|
19
|
+
* Config types are NOT here: a config is one element's private input, mirrored in that
|
|
20
|
+
* element's own module. A response is what crosses `window.crtr.respond`, so it is
|
|
21
|
+
* shared.
|
|
22
|
+
*/
|
|
23
|
+
export {};
|
|
@@ -3,6 +3,8 @@ import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';
|
|
|
3
3
|
/** Seconds a leading `sleep ...` will block for, or null when the command does
|
|
4
4
|
* not open with a sleep (or its duration isn't statically knowable). */
|
|
5
5
|
export declare function leadingSleepSeconds(command: string): number | null;
|
|
6
|
-
/** The valve's BashOperations backend.
|
|
7
|
-
|
|
6
|
+
/** The valve's BashOperations backend. Each tool execution closes over its own
|
|
7
|
+
* `takePurpose`, so concurrent calls cannot exchange labels. It is consumed even
|
|
8
|
+
* when the command is invalid or refused, leaving no state to leak later. */
|
|
9
|
+
export declare function createValveOperations(nodeId: string, contextDir: string, takePurpose?: () => string | null): BashOperations;
|
|
8
10
|
export default function (pi: ExtensionAPI): void;
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
import { spawn } from 'node:child_process';
|
|
28
28
|
import { closeSync, existsSync, mkdirSync, openSync, readFileSync, readSync, rmSync, statSync, writeFileSync, } from 'node:fs';
|
|
29
29
|
import { homedir } from 'node:os';
|
|
30
|
-
import { backgroundBashJob, bashJobPaths, formatBashElapsed, newBashJobId } from '../core/bash-jobs.js';
|
|
30
|
+
import { backgroundBashJob, bashJobPaths, formatBashElapsed, newBashJobId, normalizeBashJobPurpose } from '../core/bash-jobs.js';
|
|
31
31
|
import { Type } from 'typebox';
|
|
32
32
|
import { createBashToolDefinition } from '@earendil-works/pi-coding-agent';
|
|
33
33
|
// ---------------------------------------------------------------------------
|
|
@@ -203,11 +203,14 @@ function resolveExecutionCwd(cwd) {
|
|
|
203
203
|
warning: `[working directory no longer exists: ${cwd}; running from ${fallback}]\n`,
|
|
204
204
|
};
|
|
205
205
|
}
|
|
206
|
-
/** The valve's BashOperations backend.
|
|
207
|
-
|
|
206
|
+
/** The valve's BashOperations backend. Each tool execution closes over its own
|
|
207
|
+
* `takePurpose`, so concurrent calls cannot exchange labels. It is consumed even
|
|
208
|
+
* when the command is invalid or refused, leaving no state to leak later. */
|
|
209
|
+
export function createValveOperations(nodeId, contextDir, takePurpose = () => null) {
|
|
208
210
|
return {
|
|
209
211
|
exec: (command, cwd, { onData, signal, timeout, env }) => {
|
|
210
212
|
return new Promise((resolve, reject) => {
|
|
213
|
+
const purpose = takePurpose();
|
|
211
214
|
if (signal?.aborted) {
|
|
212
215
|
reject(new Error('aborted'));
|
|
213
216
|
return;
|
|
@@ -222,6 +225,8 @@ export function createValveOperations(nodeId, contextDir) {
|
|
|
222
225
|
writeFileSync(paths.cmdSh, command);
|
|
223
226
|
writeFileSync(paths.jobLog, '');
|
|
224
227
|
writeFileSync(paths.jobRun, '');
|
|
228
|
+
if (purpose !== null)
|
|
229
|
+
writeFileSync(paths.jobPurpose, purpose);
|
|
225
230
|
let offset = 0;
|
|
226
231
|
let settled = false;
|
|
227
232
|
let pgid;
|
|
@@ -357,8 +362,10 @@ export function createValveOperations(nodeId, contextDir) {
|
|
|
357
362
|
// parsing partial JSON can show the label while the command is still being
|
|
358
363
|
// written, rather than after the call is complete and about to finish.
|
|
359
364
|
//
|
|
360
|
-
// The
|
|
361
|
-
//
|
|
365
|
+
// The command execution path ignores it as shell input — this remains a
|
|
366
|
+
// labelling channel, not an execution parameter. The valve only persists the
|
|
367
|
+
// label beside a background job. Optional, so a model that omits it behaves
|
|
368
|
+
// exactly as before.
|
|
362
369
|
//
|
|
363
370
|
// Upstream ask: pi's own bash tool should carry this (Claude Code's bash tool
|
|
364
371
|
// has shipped an equivalent `description` field for years). Until it does, the
|
|
@@ -386,6 +393,18 @@ function withPurpose(definition) {
|
|
|
386
393
|
}),
|
|
387
394
|
};
|
|
388
395
|
}
|
|
396
|
+
/** Bind each purpose directly to its own tool execution. Pi may preflight a
|
|
397
|
+
* batch before starting its calls, so a shared "next purpose" slot could give
|
|
398
|
+
* a concurrent call the wrong label. */
|
|
399
|
+
function createPurposeValveToolDefinition(nodeId, contextDir, cwd) {
|
|
400
|
+
const schemaDefinition = withPurpose(createBashToolDefinition(cwd, { operations: createValveOperations(nodeId, contextDir) }));
|
|
401
|
+
const execute = (toolCallId, params, signal, onUpdate, ctx) => {
|
|
402
|
+
const purpose = normalizeBashJobPurpose(params['purpose']);
|
|
403
|
+
const definition = createBashToolDefinition(cwd, { operations: createValveOperations(nodeId, contextDir, () => purpose) });
|
|
404
|
+
return definition.execute(toolCallId, params, signal, onUpdate, ctx);
|
|
405
|
+
};
|
|
406
|
+
return { ...schemaDefinition, execute };
|
|
407
|
+
}
|
|
389
408
|
export default function (pi) {
|
|
390
409
|
const nodeId = process.env['CRTR_NODE_ID'];
|
|
391
410
|
if (nodeId === undefined || nodeId.trim() === '')
|
|
@@ -399,7 +418,6 @@ export default function (pi) {
|
|
|
399
418
|
// is built against. registerTool replaces the builtin by name; re-firing on
|
|
400
419
|
// every session_start is idempotent (last registration wins).
|
|
401
420
|
pi.on('session_start', (_event, ctx) => {
|
|
402
|
-
|
|
403
|
-
pi.registerTool(withPurpose(createBashToolDefinition(ctx.cwd, { operations })));
|
|
421
|
+
pi.registerTool(createPurposeValveToolDefinition(nodeId, contextDir, ctx.cwd));
|
|
404
422
|
});
|
|
405
423
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -185,6 +185,10 @@ export interface ScopeConfig {
|
|
|
185
185
|
/** Play the whip header animation whenever the human sends a prompt, and once
|
|
186
186
|
* when an automatically opened managed-child viewer starts. Default false. */
|
|
187
187
|
whip_mode: boolean;
|
|
188
|
+
/** Teach agent help the HTML page-authoring dialect. Off keeps page authoring Markdown-only. */
|
|
189
|
+
html_pages: boolean;
|
|
190
|
+
/** Product-registered page slot kinds beyond crtr's built-in catalog. */
|
|
191
|
+
page_components: string[];
|
|
188
192
|
/** Playful urgency messages the attach-viewer whip action sends to an agent. Missing, malformed, or empty lists fall back to the built-in rotation. */
|
|
189
193
|
whip_messages: string[];
|
|
190
194
|
/** Initial mouse wheel scrolling mode for each attach viewer. `tmux` follows
|
package/dist/types.js
CHANGED
|
@@ -78,6 +78,8 @@ export function defaultScopeConfig() {
|
|
|
78
78
|
completion_bell: true,
|
|
79
79
|
working_gerunds: [...DEFAULT_WORKING_GERUNDS],
|
|
80
80
|
whip_mode: false,
|
|
81
|
+
html_pages: false,
|
|
82
|
+
page_components: [],
|
|
81
83
|
whip_messages: [...DEFAULT_WHIP_MESSAGES],
|
|
82
84
|
mouse_mode_default: 'tmux',
|
|
83
85
|
live_cycles: DEFAULT_LIVE_CYCLES,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@north-light/crouter",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.194",
|
|
4
4
|
"description": "crtr — agent runtime with memory, plugins, and marketplaces",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -86,9 +86,9 @@
|
|
|
86
86
|
"test:seam": "npm run build && node --test --test-concurrency=1 --test-timeout=180000 'dist/**/__tests__/seam/*.test.js'"
|
|
87
87
|
},
|
|
88
88
|
"overrides": {
|
|
89
|
-
"@earendil-works/pi-ai": "0.
|
|
90
|
-
"@earendil-works/pi-agent-core": "0.
|
|
91
|
-
"@earendil-works/pi-tui": "0.
|
|
89
|
+
"@earendil-works/pi-ai": "0.84.1",
|
|
90
|
+
"@earendil-works/pi-agent-core": "0.84.1",
|
|
91
|
+
"@earendil-works/pi-tui": "0.84.1"
|
|
92
92
|
},
|
|
93
93
|
"repository": {
|
|
94
94
|
"type": "git",
|
|
@@ -99,10 +99,10 @@
|
|
|
99
99
|
},
|
|
100
100
|
"license": "MIT",
|
|
101
101
|
"dependencies": {
|
|
102
|
-
"@earendil-works/pi-agent-core": "0.
|
|
103
|
-
"@earendil-works/pi-ai": "0.
|
|
104
|
-
"@earendil-works/pi-coding-agent": "0.
|
|
105
|
-
"@earendil-works/pi-tui": "0.
|
|
102
|
+
"@earendil-works/pi-agent-core": "0.84.1",
|
|
103
|
+
"@earendil-works/pi-ai": "0.84.1",
|
|
104
|
+
"@earendil-works/pi-coding-agent": "0.84.1",
|
|
105
|
+
"@earendil-works/pi-tui": "0.84.1",
|
|
106
106
|
"cron-parser": "^5.6.0",
|
|
107
107
|
"proper-lockfile": "4.1.2",
|
|
108
108
|
"string-width": "^7.0.0",
|