reflectt-node 0.1.8 → 0.1.12
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/defaults/TEAM-ROLES.yaml +317 -5
- package/dist/agent-config.d.ts +51 -0
- package/dist/agent-config.d.ts.map +1 -0
- package/dist/agent-config.js +129 -0
- package/dist/agent-config.js.map +1 -0
- package/dist/agent-config.test.d.ts +2 -0
- package/dist/agent-config.test.d.ts.map +1 -0
- package/dist/agent-config.test.js +91 -0
- package/dist/agent-config.test.js.map +1 -0
- package/dist/agent-memories.d.ts +58 -0
- package/dist/agent-memories.d.ts.map +1 -0
- package/dist/agent-memories.js +168 -0
- package/dist/agent-memories.js.map +1 -0
- package/dist/agent-memories.test.d.ts +2 -0
- package/dist/agent-memories.test.d.ts.map +1 -0
- package/dist/agent-memories.test.js +327 -0
- package/dist/agent-memories.test.js.map +1 -0
- package/dist/agent-messaging.d.ts +50 -0
- package/dist/agent-messaging.d.ts.map +1 -0
- package/dist/agent-messaging.js +103 -0
- package/dist/agent-messaging.js.map +1 -0
- package/dist/agent-messaging.test.d.ts +2 -0
- package/dist/agent-messaging.test.d.ts.map +1 -0
- package/dist/agent-messaging.test.js +105 -0
- package/dist/agent-messaging.test.js.map +1 -0
- package/dist/agent-runs.d.ts +158 -0
- package/dist/agent-runs.d.ts.map +1 -0
- package/dist/agent-runs.js +514 -0
- package/dist/agent-runs.js.map +1 -0
- package/dist/agent-runs.test.d.ts +2 -0
- package/dist/agent-runs.test.d.ts.map +1 -0
- package/dist/agent-runs.test.js +386 -0
- package/dist/agent-runs.test.js.map +1 -0
- package/dist/approval-queue.test.d.ts +2 -0
- package/dist/approval-queue.test.d.ts.map +1 -0
- package/dist/approval-queue.test.js +118 -0
- package/dist/approval-queue.test.js.map +1 -0
- package/dist/artifact-store.d.ts +55 -0
- package/dist/artifact-store.d.ts.map +1 -0
- package/dist/artifact-store.js +128 -0
- package/dist/artifact-store.js.map +1 -0
- package/dist/artifact-store.test.d.ts +2 -0
- package/dist/artifact-store.test.d.ts.map +1 -0
- package/dist/artifact-store.test.js +119 -0
- package/dist/artifact-store.test.js.map +1 -0
- package/dist/boardHealthWorker.d.ts +28 -0
- package/dist/boardHealthWorker.d.ts.map +1 -1
- package/dist/boardHealthWorker.js +33 -1
- package/dist/boardHealthWorker.js.map +1 -1
- package/dist/canvas-input.test.d.ts +2 -0
- package/dist/canvas-input.test.d.ts.map +1 -0
- package/dist/canvas-input.test.js +96 -0
- package/dist/canvas-input.test.js.map +1 -0
- package/dist/canvas-render.test.d.ts +2 -0
- package/dist/canvas-render.test.d.ts.map +1 -0
- package/dist/canvas-render.test.js +95 -0
- package/dist/canvas-render.test.js.map +1 -0
- package/dist/capabilities/browser.d.ts +75 -0
- package/dist/capabilities/browser.d.ts.map +1 -0
- package/dist/capabilities/browser.js +172 -0
- package/dist/capabilities/browser.js.map +1 -0
- package/dist/channels.d.ts +1 -1
- package/dist/cli.js +4 -2
- package/dist/cli.js.map +1 -1
- package/dist/cloud.d.ts +2 -0
- package/dist/cloud.d.ts.map +1 -1
- package/dist/cloud.js +135 -3
- package/dist/cloud.js.map +1 -1
- package/dist/cost-enforcement.d.ts +38 -0
- package/dist/cost-enforcement.d.ts.map +1 -0
- package/dist/cost-enforcement.js +84 -0
- package/dist/cost-enforcement.js.map +1 -0
- package/dist/dashboard.d.ts.map +1 -1
- package/dist/dashboard.js +8 -0
- package/dist/dashboard.js.map +1 -1
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +131 -0
- package/dist/db.js.map +1 -1
- package/dist/e2e-loop-proof.test.d.ts +2 -0
- package/dist/e2e-loop-proof.test.d.ts.map +1 -0
- package/dist/e2e-loop-proof.test.js +104 -0
- package/dist/e2e-loop-proof.test.js.map +1 -0
- package/dist/email-sms-send.test.d.ts +2 -0
- package/dist/email-sms-send.test.d.ts.map +1 -0
- package/dist/email-sms-send.test.js +96 -0
- package/dist/email-sms-send.test.js.map +1 -0
- package/dist/events.d.ts +1 -1
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +2 -0
- package/dist/events.js.map +1 -1
- package/dist/fingerprint.d.ts.map +1 -1
- package/dist/fingerprint.js +5 -10
- package/dist/fingerprint.js.map +1 -1
- package/dist/github-webhook-chat.d.ts +75 -0
- package/dist/github-webhook-chat.d.ts.map +1 -0
- package/dist/github-webhook-chat.js +108 -0
- package/dist/github-webhook-chat.js.map +1 -0
- package/dist/handoff-state.test.d.ts +2 -0
- package/dist/handoff-state.test.d.ts.map +1 -0
- package/dist/handoff-state.test.js +102 -0
- package/dist/handoff-state.test.js.map +1 -0
- package/dist/health.d.ts +9 -0
- package/dist/health.d.ts.map +1 -1
- package/dist/health.js +18 -0
- package/dist/health.js.map +1 -1
- package/dist/host-error-correlation.d.ts +65 -0
- package/dist/host-error-correlation.d.ts.map +1 -0
- package/dist/host-error-correlation.js +123 -0
- package/dist/host-error-correlation.js.map +1 -0
- package/dist/index.js +39 -10
- package/dist/index.js.map +1 -1
- package/dist/notificationDedupeGuard.d.ts +4 -0
- package/dist/notificationDedupeGuard.d.ts.map +1 -1
- package/dist/notificationDedupeGuard.js +8 -4
- package/dist/notificationDedupeGuard.js.map +1 -1
- package/dist/presence.d.ts +37 -5
- package/dist/presence.d.ts.map +1 -1
- package/dist/presence.js +127 -16
- package/dist/presence.js.map +1 -1
- package/dist/review-sla.d.ts +9 -0
- package/dist/review-sla.d.ts.map +1 -0
- package/dist/review-sla.js +51 -0
- package/dist/review-sla.js.map +1 -0
- package/dist/routing-enforcement.test.d.ts +2 -0
- package/dist/routing-enforcement.test.d.ts.map +1 -0
- package/dist/routing-enforcement.test.js +86 -0
- package/dist/routing-enforcement.test.js.map +1 -0
- package/dist/run-retention.test.d.ts +2 -0
- package/dist/run-retention.test.d.ts.map +1 -0
- package/dist/run-retention.test.js +57 -0
- package/dist/run-retention.test.js.map +1 -0
- package/dist/run-stream.test.d.ts +2 -0
- package/dist/run-stream.test.d.ts.map +1 -0
- package/dist/run-stream.test.js +70 -0
- package/dist/run-stream.test.js.map +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +1301 -75
- package/dist/server.js.map +1 -1
- package/dist/tasks.d.ts.map +1 -1
- package/dist/tasks.js +45 -0
- package/dist/tasks.js.map +1 -1
- package/dist/todoHoardingGuard.d.ts +17 -0
- package/dist/todoHoardingGuard.d.ts.map +1 -1
- package/dist/todoHoardingGuard.js +25 -2
- package/dist/todoHoardingGuard.js.map +1 -1
- package/dist/webhook-storage.d.ts +50 -0
- package/dist/webhook-storage.d.ts.map +1 -0
- package/dist/webhook-storage.js +102 -0
- package/dist/webhook-storage.js.map +1 -0
- package/dist/webhook-storage.test.d.ts +2 -0
- package/dist/webhook-storage.test.d.ts.map +1 -0
- package/dist/webhook-storage.test.js +86 -0
- package/dist/webhook-storage.test.js.map +1 -0
- package/dist/workflow-templates.d.ts +44 -0
- package/dist/workflow-templates.d.ts.map +1 -0
- package/dist/workflow-templates.js +154 -0
- package/dist/workflow-templates.js.map +1 -0
- package/dist/workflow-templates.test.d.ts +2 -0
- package/dist/workflow-templates.test.d.ts.map +1 -0
- package/dist/workflow-templates.test.js +76 -0
- package/dist/workflow-templates.test.js.map +1 -0
- package/package.json +3 -1
- package/public/dashboard.js +76 -1
- package/public/design-tokens-platform.md +118 -0
- package/public/design-tokens.css +195 -0
- package/public/docs.md +131 -2
- package/public/presence-loop-demo.html +473 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
import { describe, it } from 'node:test';
|
|
3
|
+
import assert from 'node:assert/strict';
|
|
4
|
+
const VALID_ACTIONS = ['decision', 'interrupt', 'pause', 'resume', 'mute', 'unmute'];
|
|
5
|
+
const VALID_CHOICES = ['approve', 'deny', 'defer'];
|
|
6
|
+
function validateCanvasInput(body) {
|
|
7
|
+
const action = body.action;
|
|
8
|
+
if (!VALID_ACTIONS.includes(action)) {
|
|
9
|
+
return { valid: false, error: `action must be one of: ${VALID_ACTIONS.join(', ')}` };
|
|
10
|
+
}
|
|
11
|
+
if (typeof body.actor !== 'string' || !body.actor.trim()) {
|
|
12
|
+
return { valid: false, error: 'actor is required (non-empty string)' };
|
|
13
|
+
}
|
|
14
|
+
if (action === 'decision') {
|
|
15
|
+
if (!body.decisionId)
|
|
16
|
+
return { valid: false, error: 'decision action requires decisionId' };
|
|
17
|
+
if (!VALID_CHOICES.includes(body.choice)) {
|
|
18
|
+
return { valid: false, error: `decision action requires choice: ${VALID_CHOICES.join(', ')}` };
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return { valid: true };
|
|
22
|
+
}
|
|
23
|
+
describe('canvas input validation', () => {
|
|
24
|
+
it('accepts valid decision input', () => {
|
|
25
|
+
const r = validateCanvasInput({
|
|
26
|
+
action: 'decision',
|
|
27
|
+
actor: 'ryan',
|
|
28
|
+
decisionId: 'dec-123',
|
|
29
|
+
choice: 'approve',
|
|
30
|
+
});
|
|
31
|
+
assert.equal(r.valid, true);
|
|
32
|
+
});
|
|
33
|
+
it('accepts valid interrupt input', () => {
|
|
34
|
+
const r = validateCanvasInput({
|
|
35
|
+
action: 'interrupt',
|
|
36
|
+
actor: 'ryan',
|
|
37
|
+
targetRunId: 'arun-123',
|
|
38
|
+
});
|
|
39
|
+
assert.equal(r.valid, true);
|
|
40
|
+
});
|
|
41
|
+
it('accepts valid pause input', () => {
|
|
42
|
+
const r = validateCanvasInput({ action: 'pause', actor: 'ryan' });
|
|
43
|
+
assert.equal(r.valid, true);
|
|
44
|
+
});
|
|
45
|
+
it('accepts valid resume input', () => {
|
|
46
|
+
const r = validateCanvasInput({ action: 'resume', actor: 'ryan' });
|
|
47
|
+
assert.equal(r.valid, true);
|
|
48
|
+
});
|
|
49
|
+
it('accepts valid mute input', () => {
|
|
50
|
+
const r = validateCanvasInput({ action: 'mute', actor: 'ryan' });
|
|
51
|
+
assert.equal(r.valid, true);
|
|
52
|
+
});
|
|
53
|
+
it('accepts valid unmute input', () => {
|
|
54
|
+
const r = validateCanvasInput({ action: 'unmute', actor: 'ryan' });
|
|
55
|
+
assert.equal(r.valid, true);
|
|
56
|
+
});
|
|
57
|
+
it('rejects missing actor', () => {
|
|
58
|
+
const r = validateCanvasInput({ action: 'interrupt' });
|
|
59
|
+
assert.equal(r.valid, false);
|
|
60
|
+
assert.ok(r.error?.includes('actor'));
|
|
61
|
+
});
|
|
62
|
+
it('rejects invalid action', () => {
|
|
63
|
+
const r = validateCanvasInput({ action: 'explode', actor: 'ryan' });
|
|
64
|
+
assert.equal(r.valid, false);
|
|
65
|
+
assert.ok(r.error?.includes('action'));
|
|
66
|
+
});
|
|
67
|
+
it('rejects decision without decisionId', () => {
|
|
68
|
+
const r = validateCanvasInput({ action: 'decision', actor: 'ryan', choice: 'approve' });
|
|
69
|
+
assert.equal(r.valid, false);
|
|
70
|
+
assert.ok(r.error?.includes('decisionId'));
|
|
71
|
+
});
|
|
72
|
+
it('rejects decision without choice', () => {
|
|
73
|
+
const r = validateCanvasInput({ action: 'decision', actor: 'ryan', decisionId: 'dec-1' });
|
|
74
|
+
assert.equal(r.valid, false);
|
|
75
|
+
assert.ok(r.error?.includes('choice'));
|
|
76
|
+
});
|
|
77
|
+
it('rejects decision with invalid choice', () => {
|
|
78
|
+
const r = validateCanvasInput({ action: 'decision', actor: 'ryan', decisionId: 'dec-1', choice: 'maybe' });
|
|
79
|
+
assert.equal(r.valid, false);
|
|
80
|
+
assert.ok(r.error?.includes('choice'));
|
|
81
|
+
});
|
|
82
|
+
it('accepts all valid decision choices', () => {
|
|
83
|
+
for (const choice of VALID_CHOICES) {
|
|
84
|
+
const r = validateCanvasInput({ action: 'decision', actor: 'ryan', decisionId: 'dec-1', choice });
|
|
85
|
+
assert.equal(r.valid, true, `Expected ${choice} to be valid`);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
it('accepts all valid actions', () => {
|
|
89
|
+
for (const action of VALID_ACTIONS) {
|
|
90
|
+
const extra = action === 'decision' ? { decisionId: 'd-1', choice: 'approve' } : {};
|
|
91
|
+
const r = validateCanvasInput({ action, actor: 'ryan', ...extra });
|
|
92
|
+
assert.equal(r.valid, true, `Expected ${action} to be valid`);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
//# sourceMappingURL=canvas-input.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canvas-input.test.js","sourceRoot":"","sources":["../src/canvas-input.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canvas-render.test.d.ts","sourceRoot":"","sources":["../src/canvas-render.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
import { describe, it } from 'node:test';
|
|
3
|
+
import assert from 'node:assert/strict';
|
|
4
|
+
const CANVAS_STATES = ['floor', 'listening', 'thinking', 'rendering', 'ambient', 'decision', 'urgent', 'handoff'];
|
|
5
|
+
const SENSOR_VALUES = [null, 'mic', 'camera', 'mic+camera'];
|
|
6
|
+
function validateCanvasRender(body) {
|
|
7
|
+
if (!CANVAS_STATES.includes(body.state)) {
|
|
8
|
+
return { valid: false, error: `state must be one of: ${CANVAS_STATES.join(', ')}` };
|
|
9
|
+
}
|
|
10
|
+
if (body.sensors !== undefined && body.sensors !== null && !['mic', 'camera', 'mic+camera'].includes(body.sensors)) {
|
|
11
|
+
return { valid: false, error: 'sensors must be null, mic, camera, or mic+camera' };
|
|
12
|
+
}
|
|
13
|
+
if (typeof body.agentId !== 'string' || !body.agentId) {
|
|
14
|
+
return { valid: false, error: 'agentId is required' };
|
|
15
|
+
}
|
|
16
|
+
// Validate decision payload if state is decision
|
|
17
|
+
if (body.state === 'decision' && body.payload) {
|
|
18
|
+
const p = body.payload;
|
|
19
|
+
if (p.decision && (!p.decision.question || !p.decision.decisionId)) {
|
|
20
|
+
return { valid: false, error: 'decision payload requires question and decisionId' };
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return { valid: true };
|
|
24
|
+
}
|
|
25
|
+
describe('canvas render state validation', () => {
|
|
26
|
+
it('accepts all 8 valid states', () => {
|
|
27
|
+
for (const state of CANVAS_STATES) {
|
|
28
|
+
const r = validateCanvasRender({ state, agentId: 'link', sensors: null });
|
|
29
|
+
assert.equal(r.valid, true, `${state} should be valid`);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
it('rejects invalid state', () => {
|
|
33
|
+
const r = validateCanvasRender({ state: 'exploding', agentId: 'link' });
|
|
34
|
+
assert.equal(r.valid, false);
|
|
35
|
+
});
|
|
36
|
+
it('accepts all valid sensor values', () => {
|
|
37
|
+
for (const s of SENSOR_VALUES) {
|
|
38
|
+
const r = validateCanvasRender({ state: 'floor', agentId: 'link', sensors: s });
|
|
39
|
+
assert.equal(r.valid, true, `sensor ${s} should be valid`);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
it('rejects invalid sensor', () => {
|
|
43
|
+
const r = validateCanvasRender({ state: 'floor', agentId: 'link', sensors: 'lidar' });
|
|
44
|
+
assert.equal(r.valid, false);
|
|
45
|
+
});
|
|
46
|
+
it('requires agentId', () => {
|
|
47
|
+
const r = validateCanvasRender({ state: 'floor' });
|
|
48
|
+
assert.equal(r.valid, false);
|
|
49
|
+
assert.ok(r.error?.includes('agentId'));
|
|
50
|
+
});
|
|
51
|
+
it('accepts floor with empty payload', () => {
|
|
52
|
+
const r = validateCanvasRender({ state: 'floor', agentId: 'link', sensors: null, payload: {} });
|
|
53
|
+
assert.equal(r.valid, true);
|
|
54
|
+
});
|
|
55
|
+
it('accepts thinking with text payload', () => {
|
|
56
|
+
const r = validateCanvasRender({ state: 'thinking', agentId: 'link', sensors: null, payload: { text: 'Working on PR...' } });
|
|
57
|
+
assert.equal(r.valid, true);
|
|
58
|
+
});
|
|
59
|
+
it('accepts decision with full decision payload', () => {
|
|
60
|
+
const r = validateCanvasRender({
|
|
61
|
+
state: 'decision', agentId: 'link', sensors: null,
|
|
62
|
+
payload: { decision: { question: 'Deploy?', decisionId: 'dec-1', expiresAt: Date.now() + 60000, autoAction: 'defer' } },
|
|
63
|
+
});
|
|
64
|
+
assert.equal(r.valid, true);
|
|
65
|
+
});
|
|
66
|
+
it('rejects decision payload missing question', () => {
|
|
67
|
+
const r = validateCanvasRender({
|
|
68
|
+
state: 'decision', agentId: 'link', sensors: null,
|
|
69
|
+
payload: { decision: { decisionId: 'dec-1' } },
|
|
70
|
+
});
|
|
71
|
+
assert.equal(r.valid, false);
|
|
72
|
+
});
|
|
73
|
+
it('accepts handoff with summary payload', () => {
|
|
74
|
+
const r = validateCanvasRender({
|
|
75
|
+
state: 'handoff', agentId: 'link', sensors: null,
|
|
76
|
+
payload: { summary: { headline: 'Session complete', items: ['3 PRs merged'], cost: '$0.42', duration: '2h' } },
|
|
77
|
+
});
|
|
78
|
+
assert.equal(r.valid, true);
|
|
79
|
+
});
|
|
80
|
+
it('accepts ambient with agents list', () => {
|
|
81
|
+
const r = validateCanvasRender({
|
|
82
|
+
state: 'ambient', agentId: 'link', sensors: null,
|
|
83
|
+
payload: { agents: [{ name: 'link', state: 'idle' }, { name: 'pixel', state: 'working', task: 'UX flow' }] },
|
|
84
|
+
});
|
|
85
|
+
assert.equal(r.valid, true);
|
|
86
|
+
});
|
|
87
|
+
it('accepts urgent with mic sensor', () => {
|
|
88
|
+
const r = validateCanvasRender({
|
|
89
|
+
state: 'urgent', agentId: 'link', sensors: 'mic',
|
|
90
|
+
payload: { text: 'Server down!' },
|
|
91
|
+
});
|
|
92
|
+
assert.equal(r.valid, true);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
//# sourceMappingURL=canvas-render.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canvas-render.test.js","sourceRoot":"","sources":["../src/canvas-render.test.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,MAAM,MAAM,oBAAoB,CAAA;AAEvC,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,CAAU,CAAA;AAC1H,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,CAAU,CAAA;AAEpE,SAAS,oBAAoB,CAAC,IAA6B;IACzD,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAY,CAAC,EAAE,CAAC;QAC/C,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,yBAAyB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAA;IACrF,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAiB,CAAC,EAAE,CAAC;QAC7H,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,kDAAkD,EAAE,CAAA;IACpF,CAAC;IACD,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QACtD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,qBAAqB,EAAE,CAAA;IACvD,CAAC;IACD,iDAAiD;IACjD,IAAI,IAAI,CAAC,KAAK,KAAK,UAAU,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QAC9C,MAAM,CAAC,GAAG,IAAI,CAAC,OAAc,CAAA;QAC7B,IAAI,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YACnE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,mDAAmD,EAAE,CAAA;QACrF,CAAC;IACH,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;AACxB,CAAC;AAED,QAAQ,CAAC,gCAAgC,EAAE,GAAG,EAAE;IAC9C,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE,CAAC;YAClC,MAAM,CAAC,GAAG,oBAAoB,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;YACzE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,KAAK,kBAAkB,CAAC,CAAA;QACzD,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,uBAAuB,EAAE,GAAG,EAAE;QAC/B,MAAM,CAAC,GAAG,oBAAoB,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAA;QACvE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;IAC9B,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,KAAK,MAAM,CAAC,IAAI,aAAa,EAAE,CAAC;YAC9B,MAAM,CAAC,GAAG,oBAAoB,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAA;YAC/E,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,UAAU,CAAC,kBAAkB,CAAC,CAAA;QAC5D,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;QAChC,MAAM,CAAC,GAAG,oBAAoB,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAA;QACrF,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;IAC9B,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAC1B,MAAM,CAAC,GAAG,oBAAoB,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAA;QAClD,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;QAC5B,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAA;IACzC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,CAAC,GAAG,oBAAoB,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAA;QAC/F,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;IAC7B,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,CAAC,GAAG,oBAAoB,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,CAAC,CAAA;QAC5H,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;IAC7B,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,CAAC,GAAG,oBAAoB,CAAC;YAC7B,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI;YACjD,OAAO,EAAE,EAAE,QAAQ,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE;SACxH,CAAC,CAAA;QACF,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;IAC7B,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,CAAC,GAAG,oBAAoB,CAAC;YAC7B,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI;YACjD,OAAO,EAAE,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE;SAC/C,CAAC,CAAA;QACF,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;IAC9B,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,CAAC,GAAG,oBAAoB,CAAC;YAC7B,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI;YAChD,OAAO,EAAE,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,kBAAkB,EAAE,KAAK,EAAE,CAAC,cAAc,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE;SAC/G,CAAC,CAAA;QACF,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;IAC7B,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,CAAC,GAAG,oBAAoB,CAAC;YAC7B,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI;YAChD,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,EAAE;SAC7G,CAAC,CAAA;QACF,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;IAC7B,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,MAAM,CAAC,GAAG,oBAAoB,CAAC;YAC7B,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK;YAChD,OAAO,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE;SAClC,CAAC,CAAA;QACF,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;IAC7B,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser capability — local Stagehand integration.
|
|
3
|
+
*
|
|
4
|
+
* Provides isolated browser sessions that agents can create and control
|
|
5
|
+
* via HTTP. Sessions auto-close after a configurable idle timeout.
|
|
6
|
+
*
|
|
7
|
+
* @module capabilities/browser
|
|
8
|
+
*/
|
|
9
|
+
export interface BrowserConfig {
|
|
10
|
+
/** Maximum concurrent sessions (default: 3) */
|
|
11
|
+
maxConcurrentSessions: number;
|
|
12
|
+
/** Maximum sessions per hour per agent (default: 10) */
|
|
13
|
+
maxSessionsPerHour: number;
|
|
14
|
+
/** Session idle timeout in ms before auto-close (default: 5 min) */
|
|
15
|
+
idleTimeoutMs: number;
|
|
16
|
+
/** Run headless (default: true) */
|
|
17
|
+
headless: boolean;
|
|
18
|
+
/** Viewport dimensions */
|
|
19
|
+
viewport: {
|
|
20
|
+
width: number;
|
|
21
|
+
height: number;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export interface BrowserSession {
|
|
25
|
+
id: string;
|
|
26
|
+
agent: string;
|
|
27
|
+
createdAt: number;
|
|
28
|
+
lastActivityAt: number;
|
|
29
|
+
status: 'active' | 'closing' | 'closed';
|
|
30
|
+
/** Stagehand instance (opaque, held internally) */
|
|
31
|
+
_stagehand?: unknown;
|
|
32
|
+
_page?: unknown;
|
|
33
|
+
_idleTimer?: ReturnType<typeof setTimeout>;
|
|
34
|
+
}
|
|
35
|
+
export interface CreateSessionOpts {
|
|
36
|
+
agent: string;
|
|
37
|
+
url?: string;
|
|
38
|
+
headless?: boolean;
|
|
39
|
+
viewport?: {
|
|
40
|
+
width: number;
|
|
41
|
+
height: number;
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export interface ActResult {
|
|
45
|
+
success: boolean;
|
|
46
|
+
message?: string;
|
|
47
|
+
url?: string;
|
|
48
|
+
}
|
|
49
|
+
export interface ExtractResult {
|
|
50
|
+
data: unknown;
|
|
51
|
+
}
|
|
52
|
+
export interface ObserveResult {
|
|
53
|
+
actions: Array<{
|
|
54
|
+
description: string;
|
|
55
|
+
selector?: string;
|
|
56
|
+
}>;
|
|
57
|
+
}
|
|
58
|
+
export declare function configureBrowser(overrides: Partial<BrowserConfig>): void;
|
|
59
|
+
export declare function getBrowserConfig(): BrowserConfig;
|
|
60
|
+
export declare function createSession(opts: CreateSessionOpts): Promise<BrowserSession>;
|
|
61
|
+
export declare function getSession(sessionId: string): BrowserSession | undefined;
|
|
62
|
+
export declare function listSessions(): Array<Omit<BrowserSession, '_stagehand' | '_page' | '_idleTimer'>>;
|
|
63
|
+
export declare function closeSession(sessionId: string): Promise<void>;
|
|
64
|
+
export declare function closeAllSessions(): Promise<void>;
|
|
65
|
+
export declare function act(sessionId: string, instruction: string): Promise<ActResult>;
|
|
66
|
+
export declare function extract(sessionId: string, instruction: string, schema?: unknown): Promise<ExtractResult>;
|
|
67
|
+
export declare function observe(sessionId: string, instruction: string): Promise<ObserveResult>;
|
|
68
|
+
export declare function navigate(sessionId: string, url: string): Promise<{
|
|
69
|
+
url: string;
|
|
70
|
+
}>;
|
|
71
|
+
export declare function screenshot(sessionId: string): Promise<{
|
|
72
|
+
base64: string;
|
|
73
|
+
mimeType: string;
|
|
74
|
+
}>;
|
|
75
|
+
//# sourceMappingURL=browser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/capabilities/browser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser capability — local Stagehand integration.
|
|
3
|
+
*
|
|
4
|
+
* Provides isolated browser sessions that agents can create and control
|
|
5
|
+
* via HTTP. Sessions auto-close after a configurable idle timeout.
|
|
6
|
+
*
|
|
7
|
+
* @module capabilities/browser
|
|
8
|
+
*/
|
|
9
|
+
import { randomUUID } from 'node:crypto';
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
// Rate limiter (per-agent, rolling 1h window)
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
const agentSessionCounts = new Map();
|
|
14
|
+
function checkRateLimit(agent, max) {
|
|
15
|
+
const now = Date.now();
|
|
16
|
+
const hourAgo = now - 3_600_000;
|
|
17
|
+
const timestamps = (agentSessionCounts.get(agent) ?? []).filter((t) => t > hourAgo);
|
|
18
|
+
agentSessionCounts.set(agent, timestamps);
|
|
19
|
+
return timestamps.length < max;
|
|
20
|
+
}
|
|
21
|
+
function recordSession(agent) {
|
|
22
|
+
const timestamps = agentSessionCounts.get(agent) ?? [];
|
|
23
|
+
timestamps.push(Date.now());
|
|
24
|
+
agentSessionCounts.set(agent, timestamps);
|
|
25
|
+
}
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// Session manager
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
const sessions = new Map();
|
|
30
|
+
const DEFAULT_CONFIG = {
|
|
31
|
+
maxConcurrentSessions: 3,
|
|
32
|
+
maxSessionsPerHour: 10,
|
|
33
|
+
idleTimeoutMs: 5 * 60 * 1000, // 5 minutes
|
|
34
|
+
headless: true,
|
|
35
|
+
viewport: { width: 1280, height: 720 },
|
|
36
|
+
};
|
|
37
|
+
let config = { ...DEFAULT_CONFIG };
|
|
38
|
+
export function configureBrowser(overrides) {
|
|
39
|
+
config = { ...config, ...overrides };
|
|
40
|
+
}
|
|
41
|
+
export function getBrowserConfig() {
|
|
42
|
+
return { ...config };
|
|
43
|
+
}
|
|
44
|
+
function touchSession(session) {
|
|
45
|
+
session.lastActivityAt = Date.now();
|
|
46
|
+
if (session._idleTimer)
|
|
47
|
+
clearTimeout(session._idleTimer);
|
|
48
|
+
session._idleTimer = setTimeout(() => {
|
|
49
|
+
closeSession(session.id).catch((err) => console.warn(`⚠️ Browser session ${session.id} idle-close failed:`, err));
|
|
50
|
+
}, config.idleTimeoutMs);
|
|
51
|
+
}
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
// Public API
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
export async function createSession(opts) {
|
|
56
|
+
// Validate limits
|
|
57
|
+
const activeSessions = [...sessions.values()].filter((s) => s.status === 'active');
|
|
58
|
+
if (activeSessions.length >= config.maxConcurrentSessions) {
|
|
59
|
+
throw new Error(`Max concurrent browser sessions reached (${config.maxConcurrentSessions}). Close an existing session first.`);
|
|
60
|
+
}
|
|
61
|
+
if (!checkRateLimit(opts.agent, config.maxSessionsPerHour)) {
|
|
62
|
+
throw new Error(`Agent "${opts.agent}" exceeded max sessions per hour (${config.maxSessionsPerHour}).`);
|
|
63
|
+
}
|
|
64
|
+
// Lazy-import Stagehand (heavy dependency)
|
|
65
|
+
const { Stagehand } = await import('@browserbasehq/stagehand');
|
|
66
|
+
const stagehand = new Stagehand({
|
|
67
|
+
env: 'LOCAL',
|
|
68
|
+
verbose: 0,
|
|
69
|
+
disablePino: true,
|
|
70
|
+
disableAPI: true,
|
|
71
|
+
localBrowserLaunchOptions: {
|
|
72
|
+
headless: opts.headless ?? config.headless,
|
|
73
|
+
viewport: opts.viewport ?? config.viewport,
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
await stagehand.init();
|
|
77
|
+
recordSession(opts.agent);
|
|
78
|
+
const page = stagehand.context.pages()[0];
|
|
79
|
+
if (opts.url && page) {
|
|
80
|
+
await page.goto(opts.url, { waitUntil: 'domcontentloaded' });
|
|
81
|
+
}
|
|
82
|
+
const session = {
|
|
83
|
+
id: randomUUID(),
|
|
84
|
+
agent: opts.agent,
|
|
85
|
+
createdAt: Date.now(),
|
|
86
|
+
lastActivityAt: Date.now(),
|
|
87
|
+
status: 'active',
|
|
88
|
+
_stagehand: stagehand,
|
|
89
|
+
_page: page,
|
|
90
|
+
};
|
|
91
|
+
sessions.set(session.id, session);
|
|
92
|
+
touchSession(session);
|
|
93
|
+
return session;
|
|
94
|
+
}
|
|
95
|
+
export function getSession(sessionId) {
|
|
96
|
+
return sessions.get(sessionId);
|
|
97
|
+
}
|
|
98
|
+
export function listSessions() {
|
|
99
|
+
return [...sessions.values()].map(({ _stagehand, _page, _idleTimer, ...rest }) => rest);
|
|
100
|
+
}
|
|
101
|
+
export async function closeSession(sessionId) {
|
|
102
|
+
const session = sessions.get(sessionId);
|
|
103
|
+
if (!session)
|
|
104
|
+
return;
|
|
105
|
+
if (session.status === 'closed' || session.status === 'closing')
|
|
106
|
+
return;
|
|
107
|
+
session.status = 'closing';
|
|
108
|
+
if (session._idleTimer)
|
|
109
|
+
clearTimeout(session._idleTimer);
|
|
110
|
+
try {
|
|
111
|
+
const stagehand = session._stagehand;
|
|
112
|
+
if (stagehand) {
|
|
113
|
+
await stagehand.close();
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
console.warn(`⚠️ Browser session ${sessionId} close error:`, err);
|
|
118
|
+
}
|
|
119
|
+
session.status = 'closed';
|
|
120
|
+
session._stagehand = undefined;
|
|
121
|
+
session._page = undefined;
|
|
122
|
+
sessions.delete(sessionId);
|
|
123
|
+
}
|
|
124
|
+
export async function closeAllSessions() {
|
|
125
|
+
const ids = [...sessions.keys()];
|
|
126
|
+
await Promise.allSettled(ids.map((id) => closeSession(id)));
|
|
127
|
+
}
|
|
128
|
+
// ---------------------------------------------------------------------------
|
|
129
|
+
// Session actions (act / extract / observe / navigate / screenshot)
|
|
130
|
+
// ---------------------------------------------------------------------------
|
|
131
|
+
function getActiveStagehand(sessionId) {
|
|
132
|
+
const session = sessions.get(sessionId);
|
|
133
|
+
if (!session || session.status !== 'active') {
|
|
134
|
+
throw new Error(`No active browser session: ${sessionId}`);
|
|
135
|
+
}
|
|
136
|
+
touchSession(session);
|
|
137
|
+
return {
|
|
138
|
+
stagehand: session._stagehand,
|
|
139
|
+
page: session._page,
|
|
140
|
+
session,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
export async function act(sessionId, instruction) {
|
|
144
|
+
const { stagehand, page } = getActiveStagehand(sessionId);
|
|
145
|
+
await stagehand.act(instruction);
|
|
146
|
+
const url = page?.url?.() ?? undefined;
|
|
147
|
+
return { success: true, message: `Executed: ${instruction}`, url };
|
|
148
|
+
}
|
|
149
|
+
export async function extract(sessionId, instruction, schema) {
|
|
150
|
+
const { stagehand } = getActiveStagehand(sessionId);
|
|
151
|
+
const data = await stagehand.extract(instruction, schema);
|
|
152
|
+
return { data };
|
|
153
|
+
}
|
|
154
|
+
export async function observe(sessionId, instruction) {
|
|
155
|
+
const { stagehand } = getActiveStagehand(sessionId);
|
|
156
|
+
const actions = await stagehand.observe(instruction);
|
|
157
|
+
return { actions };
|
|
158
|
+
}
|
|
159
|
+
export async function navigate(sessionId, url) {
|
|
160
|
+
const { page } = getActiveStagehand(sessionId);
|
|
161
|
+
await page.goto(url, { waitUntil: 'domcontentloaded' });
|
|
162
|
+
return { url: page.url() };
|
|
163
|
+
}
|
|
164
|
+
export async function screenshot(sessionId) {
|
|
165
|
+
const { page } = getActiveStagehand(sessionId);
|
|
166
|
+
const buffer = await page.screenshot({ type: 'png' });
|
|
167
|
+
return {
|
|
168
|
+
base64: buffer.toString('base64'),
|
|
169
|
+
mimeType: 'image/png',
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=browser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/capabilities/browser.ts"],"names":[],"mappings":"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"}
|
package/dist/channels.d.ts
CHANGED
|
@@ -23,6 +23,6 @@ export declare const CHANNEL_DEFINITIONS: readonly [{
|
|
|
23
23
|
readonly id: "dev";
|
|
24
24
|
readonly name: "Development";
|
|
25
25
|
}];
|
|
26
|
-
export declare const DEFAULT_CHAT_CHANNELS: ("general" | "ops" | "reviews" | "
|
|
26
|
+
export declare const DEFAULT_CHAT_CHANNELS: ("general" | "ops" | "reviews" | "shipping" | "decisions" | "blockers" | "problems" | "dev")[];
|
|
27
27
|
export declare const DEFAULT_INBOX_SUBSCRIPTIONS: string[];
|
|
28
28
|
//# sourceMappingURL=channels.d.ts.map
|
package/dist/cli.js
CHANGED
|
@@ -89,9 +89,11 @@ function getRuntimePaths() {
|
|
|
89
89
|
// Detect whether running from source (dev) or dist (npm install)
|
|
90
90
|
const srcPath = join(projectRoot, 'src', 'index.ts');
|
|
91
91
|
const distPath = join(projectRoot, 'dist', 'index.js');
|
|
92
|
-
|
|
92
|
+
// In production, always use compiled dist even if src/ exists (symlink installs)
|
|
93
|
+
const forceCompiled = process.env.NODE_ENV === 'production';
|
|
94
|
+
const isSource = !forceCompiled && existsSync(srcPath);
|
|
93
95
|
const serverPath = isSource ? srcPath : distPath;
|
|
94
|
-
const useNode = !isSource; // npm install: use node directly; dev: use tsx
|
|
96
|
+
const useNode = !isSource; // npm install / production: use node directly; dev: use tsx
|
|
95
97
|
return { projectRoot, serverPath, useNode };
|
|
96
98
|
}
|
|
97
99
|
function buildServerEnv(config) {
|