@longtable/cli 0.1.9 → 0.1.10

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/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from "./prompt-aliases.js";
2
2
  export * from "./personas.js";
3
3
  export * from "./persona-router.js";
4
+ export * from "./panel.js";
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from "./prompt-aliases.js";
2
2
  export * from "./personas.js";
3
3
  export * from "./persona-router.js";
4
+ export * from "./panel.js";
@@ -0,0 +1,40 @@
1
+ import type { CheckpointSensitivity, InteractionMode, InvocationIntent, InvocationRecord, PanelPlan, PanelResult, PanelVisibility, QuestionRecord, ProviderKind, RoleKey } from "@longtable/core";
2
+ import { type CanonicalPersona } from "./personas.js";
3
+ export interface BuildPanelPlanOptions {
4
+ prompt: string;
5
+ mode?: InteractionMode;
6
+ roleFlag?: string;
7
+ roles?: CanonicalPersona[];
8
+ provider?: ProviderKind;
9
+ visibility?: PanelVisibility;
10
+ }
11
+ export interface PanelFallback {
12
+ intent: InvocationIntent;
13
+ plan: PanelPlan;
14
+ result: PanelResult;
15
+ invocationRecord: InvocationRecord;
16
+ questionRecord: QuestionRecord;
17
+ prompt: string;
18
+ }
19
+ export declare function buildPanelPlan(options: BuildPanelPlanOptions): PanelPlan;
20
+ export declare function buildInvocationIntent(options: {
21
+ prompt: string;
22
+ mode?: InteractionMode;
23
+ roles: RoleKey[];
24
+ provider?: ProviderKind;
25
+ visibility?: PanelVisibility;
26
+ checkpointSensitivity?: CheckpointSensitivity;
27
+ rationale?: string[];
28
+ }): InvocationIntent;
29
+ export declare function createPlannedPanelQuestionRecord(plan: PanelPlan, provider?: ProviderKind): QuestionRecord;
30
+ export declare function createPlannedPanelResult(plan: PanelPlan, provider?: ProviderKind, linkedQuestionRecordIds?: string[]): PanelResult;
31
+ export declare function createPlannedInvocationRecord(options: {
32
+ intent: InvocationIntent;
33
+ plan: PanelPlan;
34
+ result: PanelResult;
35
+ provider?: ProviderKind;
36
+ }): InvocationRecord;
37
+ export declare function renderSequentialFallbackPrompt(plan: PanelPlan): string;
38
+ export declare function buildPanelFallback(options: BuildPanelPlanOptions): PanelFallback;
39
+ export declare function renderPanelSummary(plan: PanelPlan): string;
40
+ export declare function listDefaultPanelRoles(): CanonicalPersona[];
package/dist/panel.js ADDED
@@ -0,0 +1,268 @@
1
+ import { getPersonaDefinition, parsePersonaKey, PERSONA_DEFINITIONS } from "./personas.js";
2
+ import { detectOutputLanguage, parseRoleFlag, routePersonas } from "./persona-router.js";
3
+ const DEFAULT_PANEL_ROLES = [
4
+ "reviewer",
5
+ "methods_critic",
6
+ "measurement_auditor",
7
+ "theory_critic"
8
+ ];
9
+ function unique(items) {
10
+ return [...new Set(items)];
11
+ }
12
+ function nowIso() {
13
+ return new Date().toISOString();
14
+ }
15
+ function createId(prefix) {
16
+ return `${prefix}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
17
+ }
18
+ function highestSensitivity(keys) {
19
+ if (keys.some((key) => getPersonaDefinition(key).checkpointSensitivity === "high")) {
20
+ return "high";
21
+ }
22
+ if (keys.some((key) => getPersonaDefinition(key).checkpointSensitivity === "medium")) {
23
+ return "medium";
24
+ }
25
+ return "low";
26
+ }
27
+ function supportsMode(key, mode) {
28
+ return getPersonaDefinition(key).supportedModes.includes(mode);
29
+ }
30
+ function reasonForRole(key, explicitRoles, routedRoles) {
31
+ if (explicitRoles.includes(key)) {
32
+ return "explicitly requested";
33
+ }
34
+ if (routedRoles.includes(key)) {
35
+ return "matched prompt language";
36
+ }
37
+ if (DEFAULT_PANEL_ROLES.includes(key)) {
38
+ return "default panel member";
39
+ }
40
+ return "panel support role";
41
+ }
42
+ function resolvePanelRoles(options) {
43
+ const mode = options.mode ?? "review";
44
+ const explicitFromFlag = parseRoleFlag(options.roleFlag);
45
+ const explicitRoles = unique([...(options.roles ?? []), ...explicitFromFlag]);
46
+ if (explicitRoles.length > 0) {
47
+ return explicitRoles.filter((role) => supportsMode(role, mode));
48
+ }
49
+ const routed = routePersonas(options.prompt).consultedRoles.filter((role) => supportsMode(role, mode));
50
+ return unique([
51
+ ...DEFAULT_PANEL_ROLES.filter((role) => supportsMode(role, mode)),
52
+ ...routed
53
+ ]);
54
+ }
55
+ function memberForRole(role, explicitRoles, routedRoles) {
56
+ const definition = getPersonaDefinition(role);
57
+ return {
58
+ role,
59
+ label: definition.label,
60
+ reason: reasonForRole(role, explicitRoles, routedRoles),
61
+ required: DEFAULT_PANEL_ROLES.includes(role) || explicitRoles.includes(role)
62
+ };
63
+ }
64
+ export function buildPanelPlan(options) {
65
+ const mode = options.mode ?? "review";
66
+ const explicitRoles = unique([...(options.roles ?? []), ...parseRoleFlag(options.roleFlag)]);
67
+ const routedRoles = routePersonas(options.prompt).consultedRoles;
68
+ const roles = resolvePanelRoles(options);
69
+ const createdAt = nowIso();
70
+ return {
71
+ id: createId("panel_plan"),
72
+ createdAt,
73
+ mode,
74
+ prompt: options.prompt,
75
+ members: roles.map((role) => memberForRole(role, explicitRoles, routedRoles)),
76
+ visibility: options.visibility ?? "always_visible",
77
+ preferredSurface: "sequential_fallback",
78
+ fallbackSurface: "sequential_fallback",
79
+ checkpointSensitivity: highestSensitivity(roles),
80
+ rationale: [
81
+ "Option A uses provider-neutral panel semantics before native provider orchestration.",
82
+ "Sequential fallback is the stable execution path for both Claude Code and Codex.",
83
+ roles.length === explicitRoles.length && explicitRoles.length > 0
84
+ ? "The panel is constrained by explicitly requested roles."
85
+ : "The panel combines default research-review roles with prompt-triggered roles."
86
+ ]
87
+ };
88
+ }
89
+ export function buildInvocationIntent(options) {
90
+ return {
91
+ id: createId("invocation"),
92
+ kind: "panel",
93
+ mode: options.mode ?? "review",
94
+ prompt: options.prompt,
95
+ roles: options.roles,
96
+ provider: options.provider,
97
+ requestedSurface: "sequential_fallback",
98
+ visibility: options.visibility ?? "always_visible",
99
+ checkpointSensitivity: options.checkpointSensitivity ?? "medium",
100
+ rationale: options.rationale ?? ["Panel invocation requested."]
101
+ };
102
+ }
103
+ export function createPlannedPanelQuestionRecord(plan, provider) {
104
+ const createdAt = nowIso();
105
+ return {
106
+ id: createId("question_record"),
107
+ createdAt,
108
+ updatedAt: createdAt,
109
+ status: "pending",
110
+ prompt: {
111
+ id: createId("question_prompt"),
112
+ checkpointKey: "panel_next_decision",
113
+ title: "Panel follow-up decision",
114
+ question: "What should LongTable treat as the next human decision after this panel review?",
115
+ type: "single_choice",
116
+ options: [
117
+ {
118
+ value: "revise",
119
+ label: "Revise before proceeding",
120
+ description: "Use the panel result to revise the claim, design, or draft first."
121
+ },
122
+ {
123
+ value: "evidence",
124
+ label: "Gather or verify evidence first",
125
+ description: "Do not proceed until the relevant evidence or citation support is checked."
126
+ },
127
+ {
128
+ value: "proceed",
129
+ label: "Proceed with current direction",
130
+ description: "Accept the risk profile and continue with the current direction."
131
+ },
132
+ {
133
+ value: "defer",
134
+ label: "Keep this open",
135
+ description: "Do not commit yet; keep the panel issue visible as an open tension."
136
+ }
137
+ ],
138
+ allowOther: true,
139
+ otherLabel: "Other decision",
140
+ required: plan.checkpointSensitivity === "high",
141
+ source: "runtime_guidance",
142
+ rationale: [
143
+ "Panel review creates disagreement or risk visibility that should connect to an explicit researcher decision.",
144
+ `Panel checkpoint sensitivity: ${plan.checkpointSensitivity}.`
145
+ ],
146
+ preferredSurfaces: provider === "claude"
147
+ ? ["native_structured", "numbered"]
148
+ : ["numbered", "native_structured"]
149
+ }
150
+ };
151
+ }
152
+ export function createPlannedPanelResult(plan, provider, linkedQuestionRecordIds = []) {
153
+ const createdAt = nowIso();
154
+ return {
155
+ id: createId("panel_result"),
156
+ planId: plan.id,
157
+ createdAt,
158
+ updatedAt: createdAt,
159
+ provider,
160
+ surface: "sequential_fallback",
161
+ status: "planned",
162
+ memberResults: plan.members.map((member) => ({
163
+ role: member.role,
164
+ label: member.label,
165
+ status: "planned"
166
+ })),
167
+ linkedQuestionRecordIds,
168
+ linkedDecisionRecordIds: []
169
+ };
170
+ }
171
+ export function createPlannedInvocationRecord(options) {
172
+ const createdAt = nowIso();
173
+ return {
174
+ id: createId("invocation_record"),
175
+ createdAt,
176
+ updatedAt: createdAt,
177
+ intent: options.intent,
178
+ status: "planned",
179
+ provider: options.provider,
180
+ surface: "sequential_fallback",
181
+ panelPlan: options.plan,
182
+ panelResult: options.result,
183
+ degradationReason: "Native provider team execution is optional; sequential fallback is the stable LongTable surface."
184
+ };
185
+ }
186
+ function roleInstruction(member) {
187
+ const key = parsePersonaKey(member.role);
188
+ const definition = key ? getPersonaDefinition(key) : null;
189
+ return [
190
+ `Role: ${member.label} (${member.role})`,
191
+ `Reason: ${member.reason}.`,
192
+ definition ? `Focus: ${definition.shortDescription}` : undefined,
193
+ "Output: claims, objections, open questions, and evidence/file references when available."
194
+ ].filter(Boolean).join("\n");
195
+ }
196
+ function languageNote(language) {
197
+ return language === "ko"
198
+ ? "Respond in Korean unless the research artifact itself requires English."
199
+ : "Respond in the user's language unless the research artifact requires another language.";
200
+ }
201
+ export function renderSequentialFallbackPrompt(plan) {
202
+ const language = detectOutputLanguage(plan.prompt);
203
+ return [
204
+ "LongTable mode: Panel",
205
+ "Execution surface: sequential_fallback",
206
+ "",
207
+ "Run this as a structured panel review. Treat each role as an independent pass, then synthesize.",
208
+ "Do not expose hidden reasoning, private tool traces, or provider chain-of-thought.",
209
+ "Make disagreement inspectable through structured role outputs.",
210
+ languageNote(language),
211
+ "",
212
+ "Panel roles:",
213
+ ...plan.members.map((member, index) => `${index + 1}. ${roleInstruction(member)}`),
214
+ "",
215
+ "Return format:",
216
+ "1. LongTable synthesis",
217
+ "2. Panel opinions by role",
218
+ "3. Conflict summary",
219
+ "4. Decision prompt for the researcher",
220
+ "5. Technical record: roles consulted, execution surface, fallback/native mode, and source/file references used",
221
+ "",
222
+ "Research object:",
223
+ plan.prompt
224
+ ].join("\n");
225
+ }
226
+ export function buildPanelFallback(options) {
227
+ const plan = buildPanelPlan(options);
228
+ const intent = buildInvocationIntent({
229
+ prompt: plan.prompt,
230
+ mode: plan.mode,
231
+ roles: plan.members.map((member) => member.role),
232
+ provider: options.provider,
233
+ visibility: plan.visibility,
234
+ checkpointSensitivity: plan.checkpointSensitivity,
235
+ rationale: plan.rationale
236
+ });
237
+ const questionRecord = createPlannedPanelQuestionRecord(plan, options.provider);
238
+ const result = createPlannedPanelResult(plan, options.provider, [questionRecord.id]);
239
+ return {
240
+ intent,
241
+ plan,
242
+ result,
243
+ invocationRecord: createPlannedInvocationRecord({
244
+ intent,
245
+ plan,
246
+ result,
247
+ provider: options.provider
248
+ }),
249
+ questionRecord,
250
+ prompt: renderSequentialFallbackPrompt(plan)
251
+ };
252
+ }
253
+ export function renderPanelSummary(plan) {
254
+ return [
255
+ "LongTable Panel Plan",
256
+ `- mode: ${plan.mode}`,
257
+ `- execution surface: ${plan.preferredSurface}`,
258
+ `- visibility: ${plan.visibility}`,
259
+ `- checkpoint sensitivity: ${plan.checkpointSensitivity}`,
260
+ "- roles:",
261
+ ...plan.members.map((member) => ` - ${member.label} (${member.role}): ${member.reason}`),
262
+ "",
263
+ "This is panel orchestration, not persistent team orchestration."
264
+ ].join("\n");
265
+ }
266
+ export function listDefaultPanelRoles() {
267
+ return PERSONA_DEFINITIONS.filter((persona) => persona.defaultPanelMember).map((persona) => persona.key);
268
+ }
@@ -1,3 +1,4 @@
1
+ import type { CheckpointSensitivity, InteractionMode, RoleDefinition } from "@longtable/core";
1
2
  export declare const CANONICAL_PERSONAS: readonly ["editor", "reviewer", "theory_critic", "methods_critic", "measurement_auditor", "ethics_reviewer", "voice_keeper", "venue_strategist"];
2
3
  export type CanonicalPersona = (typeof CANONICAL_PERSONAS)[number];
3
4
  export interface PersonaDefinition {
@@ -6,7 +7,11 @@ export interface PersonaDefinition {
6
7
  shortDescription: string;
7
8
  triggerMode: "auto-callable" | "explicit-only";
8
9
  synonyms: string[];
10
+ defaultPanelMember: boolean;
11
+ checkpointSensitivity: CheckpointSensitivity;
12
+ supportedModes: InteractionMode[];
9
13
  }
10
14
  export declare const PERSONA_DEFINITIONS: readonly PersonaDefinition[];
11
15
  export declare function parsePersonaKey(value: string): CanonicalPersona | null;
12
16
  export declare function getPersonaDefinition(key: CanonicalPersona): PersonaDefinition;
17
+ export declare function listRoleDefinitions(): RoleDefinition[];
package/dist/personas.js CHANGED
@@ -14,28 +14,40 @@ export const PERSONA_DEFINITIONS = [
14
14
  label: "Journal Editor",
15
15
  shortDescription: "Assesses venue fit, framing strength, and editorial salience.",
16
16
  triggerMode: "auto-callable",
17
- synonyms: ["editor", "journal editor", "editorial", "편집자", "저널 편집자", "에디터"]
17
+ synonyms: ["editor", "journal editor", "editorial", "편집자", "저널 편집자", "에디터"],
18
+ defaultPanelMember: false,
19
+ checkpointSensitivity: "medium",
20
+ supportedModes: ["review", "critique", "draft", "commit", "submit"]
18
21
  },
19
22
  {
20
23
  key: "reviewer",
21
24
  label: "Reviewer",
22
25
  shortDescription: "Surfaces likely peer-review objections and requests for clarification.",
23
26
  triggerMode: "auto-callable",
24
- synonyms: ["reviewer", "peer reviewer", "심사자", "리뷰어", "심사위원"]
27
+ synonyms: ["reviewer", "peer reviewer", "심사자", "리뷰어", "심사위원"],
28
+ defaultPanelMember: true,
29
+ checkpointSensitivity: "medium",
30
+ supportedModes: ["review", "critique", "draft", "commit", "submit"]
25
31
  },
26
32
  {
27
33
  key: "theory_critic",
28
34
  label: "Theory Critic",
29
35
  shortDescription: "Checks conceptual coherence, anchor theory fit, and overreach.",
30
36
  triggerMode: "auto-callable",
31
- synonyms: ["theory", "theoretical", "conceptual", "이론", "이론적", "개념적"]
37
+ synonyms: ["theory", "theoretical", "conceptual", "이론", "이론적", "개념적"],
38
+ defaultPanelMember: true,
39
+ checkpointSensitivity: "high",
40
+ supportedModes: ["explore", "review", "critique", "draft", "commit", "submit"]
32
41
  },
33
42
  {
34
43
  key: "methods_critic",
35
44
  label: "Methods Critic",
36
45
  shortDescription: "Challenges design logic, methodological defensibility, and alignment.",
37
46
  triggerMode: "auto-callable",
38
- synonyms: ["method", "methods", "methodology", "research design", "방법론", "방법", "연구 설계"]
47
+ synonyms: ["method", "methods", "methodology", "research design", "방법론", "방법", "연구 설계"],
48
+ defaultPanelMember: true,
49
+ checkpointSensitivity: "high",
50
+ supportedModes: ["explore", "review", "critique", "draft", "commit", "submit"]
39
51
  },
40
52
  {
41
53
  key: "measurement_auditor",
@@ -52,28 +64,40 @@ export const PERSONA_DEFINITIONS = [
52
64
  "척도",
53
65
  "타당도",
54
66
  "신뢰도"
55
- ]
67
+ ],
68
+ defaultPanelMember: true,
69
+ checkpointSensitivity: "high",
70
+ supportedModes: ["review", "critique", "commit", "submit"]
56
71
  },
57
72
  {
58
73
  key: "ethics_reviewer",
59
74
  label: "Ethics Reviewer",
60
75
  shortDescription: "Flags consent, IRB, representation, and trust harms.",
61
76
  triggerMode: "auto-callable",
62
- synonyms: ["ethics", "ethical", "irb", "윤리", "윤리적", "irb"]
77
+ synonyms: ["ethics", "ethical", "irb", "윤리", "윤리적", "irb"],
78
+ defaultPanelMember: false,
79
+ checkpointSensitivity: "high",
80
+ supportedModes: ["explore", "review", "critique", "commit", "submit"]
63
81
  },
64
82
  {
65
83
  key: "voice_keeper",
66
84
  label: "Voice Keeper",
67
85
  shortDescription: "Protects narrative trace, authorship, and the researcher's own voice.",
68
86
  triggerMode: "auto-callable",
69
- synonyms: ["voice", "tone", "narrative", "authorship", "목소리", "서사", "저자성", "문체"]
87
+ synonyms: ["voice", "tone", "narrative", "authorship", "목소리", "서사", "저자성", "문체"],
88
+ defaultPanelMember: false,
89
+ checkpointSensitivity: "medium",
90
+ supportedModes: ["explore", "review", "critique", "draft", "commit"]
70
91
  },
71
92
  {
72
93
  key: "venue_strategist",
73
94
  label: "Venue Strategist",
74
95
  shortDescription: "Compares venue expectations and suggests positioning tradeoffs.",
75
96
  triggerMode: "explicit-only",
76
- synonyms: ["venue", "journal fit", "conference fit", "저널 적합성", "학회 적합성", "투고처"]
97
+ synonyms: ["venue", "journal fit", "conference fit", "저널 적합성", "학회 적합성", "투고처"],
98
+ defaultPanelMember: false,
99
+ checkpointSensitivity: "medium",
100
+ supportedModes: ["review", "critique", "draft", "commit", "submit"]
77
101
  }
78
102
  ];
79
103
  export function parsePersonaKey(value) {
@@ -85,3 +109,15 @@ export function parsePersonaKey(value) {
85
109
  export function getPersonaDefinition(key) {
86
110
  return PERSONA_DEFINITIONS.find((persona) => persona.key === key);
87
111
  }
112
+ export function listRoleDefinitions() {
113
+ return PERSONA_DEFINITIONS.map((persona) => ({
114
+ key: persona.key,
115
+ label: persona.label,
116
+ shortDescription: persona.shortDescription,
117
+ triggerMode: persona.triggerMode,
118
+ synonyms: [...persona.synonyms],
119
+ defaultPanelMember: persona.defaultPanelMember,
120
+ checkpointSensitivity: persona.checkpointSensitivity,
121
+ supportedModes: [...persona.supportedModes]
122
+ }));
123
+ }
@@ -1,3 +1,4 @@
1
+ import type { DecisionRecord, InvocationRecord, ProviderKind, QuestionRecord, ResearchState } from "@longtable/core";
1
2
  import type { SetupPersistedOutput } from "@longtable/setup";
2
3
  export type ProjectDisagreementPreference = "synthesis_only" | "show_on_conflict" | "always_visible";
3
4
  export interface LongTableProjectRecord {
@@ -44,7 +45,86 @@ export interface LongTableProjectContext {
44
45
  currentFilePath: string;
45
46
  metaDir: string;
46
47
  }
48
+ export interface LongTableWorkspaceInspection {
49
+ found: boolean;
50
+ rootPath?: string;
51
+ project?: {
52
+ name: string;
53
+ path: string;
54
+ field: string;
55
+ careerStage: string;
56
+ checkpointIntensity: string;
57
+ };
58
+ session?: {
59
+ currentGoal: string;
60
+ currentBlocker?: string;
61
+ requestedPerspectives: string[];
62
+ disagreementPreference: ProjectDisagreementPreference;
63
+ };
64
+ files?: {
65
+ project: string;
66
+ session: string;
67
+ state: string;
68
+ current: string;
69
+ };
70
+ counts?: {
71
+ invocations: number;
72
+ questions: number;
73
+ pendingQuestions: number;
74
+ answeredQuestions: number;
75
+ decisions: number;
76
+ };
77
+ recentInvocations?: Array<{
78
+ id: string;
79
+ kind: string;
80
+ mode: string;
81
+ surface: string;
82
+ status: string;
83
+ roles: string[];
84
+ linkedQuestions: number;
85
+ linkedDecisions: number;
86
+ }>;
87
+ pendingQuestions?: Array<{
88
+ id: string;
89
+ title: string;
90
+ question: string;
91
+ options: string[];
92
+ required: boolean;
93
+ }>;
94
+ recentDecisions?: Array<{
95
+ id: string;
96
+ checkpointKey: string;
97
+ summary: string;
98
+ selectedOption?: string;
99
+ timestamp: string;
100
+ }>;
101
+ }
47
102
  export declare function syncCurrentWorkspaceView(context: LongTableProjectContext): Promise<string>;
103
+ export declare function appendInvocationRecordToWorkspace(context: LongTableProjectContext, invocation: InvocationRecord, questions?: QuestionRecord[]): Promise<ResearchState>;
104
+ export declare function listBlockingWorkspaceQuestions(context: LongTableProjectContext): Promise<QuestionRecord[]>;
105
+ export declare function assertWorkspaceNotBlocked(context: LongTableProjectContext): Promise<void>;
106
+ export declare function createWorkspaceQuestion(options: {
107
+ context: LongTableProjectContext;
108
+ prompt: string;
109
+ title?: string;
110
+ question?: string;
111
+ provider?: ProviderKind;
112
+ required?: boolean;
113
+ }): Promise<{
114
+ question: QuestionRecord;
115
+ state: ResearchState;
116
+ }>;
117
+ export declare function answerWorkspaceQuestion(options: {
118
+ context: LongTableProjectContext;
119
+ questionId?: string;
120
+ answer: string;
121
+ rationale?: string;
122
+ provider?: "codex" | "claude";
123
+ }): Promise<{
124
+ question: QuestionRecord;
125
+ decision: DecisionRecord;
126
+ state: ResearchState;
127
+ }>;
48
128
  export declare function createOrUpdateProjectWorkspace(options: {
49
129
  projectName: string;
50
130
  projectPath: string;
@@ -55,4 +135,5 @@ export declare function createOrUpdateProjectWorkspace(options: {
55
135
  setup: SetupPersistedOutput;
56
136
  }): Promise<LongTableProjectContext>;
57
137
  export declare function loadProjectContextFromDirectory(startPath: string): Promise<LongTableProjectContext | null>;
138
+ export declare function inspectProjectWorkspace(startPath: string): Promise<LongTableWorkspaceInspection>;
58
139
  export declare function renderProjectWorkspaceSummary(context: LongTableProjectContext): string;